zoukankan      html  css  js  c++  java
  • Codeforces Round #436 (Div. 2) 题解864A 864B 864C 864D 864E 864F

    A. Fair Game
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Petya and Vasya decided to play a game. They have n cards (n is an even number). A single integer is written on each card.

    Before the game Petya will choose an integer and after that Vasya will choose another integer (different from the number that Petya chose). During the game each player takes all the cards with number he chose. For example, if Petya chose number 5 before the game he will take all cards on which 5 is written and if Vasya chose number 10 before the game he will take all cards on which 10 is written.

    The game is considered fair if Petya and Vasya can take all n cards, and the number of cards each player gets is the same.

    Determine whether Petya and Vasya can choose integer numbers before the game so that the game is fair.

    Input

    The first line contains a single integer n (2 ≤ n ≤ 100) — number of cards. It is guaranteed that n is an even number.

    The following n lines contain a sequence of integers a1, a2, ..., an (one integer per line, 1 ≤ ai ≤ 100) — numbers written on the n cards.

    Output

    If it is impossible for Petya and Vasya to choose numbers in such a way that the game will be fair, print "NO" (without quotes) in the first line. In this case you should not print anything more.

    In the other case print "YES" (without quotes) in the first line. In the second line print two distinct integers — number that Petya should choose and the number that Vasya should choose to make the game fair. If there are several solutions, print any of them.

    Examples
    Input
    4
    11
    27
    27
    11
    Output
    YES
    11 27
    Input
    2
    6
    6
    Output
    NO
    Input
    6
    10
    20
    30
    20
    10
    20
    Output
    NO
    Input
    6
    1
    1
    2
    2
    3
    3
    Output
    NO
    Note

    In the first example the game will be fair if, for example, Petya chooses number 11, and Vasya chooses number 27. Then the will take all cards — Petya will take cards 1 and 4, and Vasya will take cards 2 and 3. Thus, each of them will take exactly two cards.

    In the second example fair game is impossible because the numbers written on the cards are equal, but the numbers that Petya and Vasya should choose should be distinct.

    In the third example it is impossible to take all cards. Petya and Vasya can take at most five cards — for example, Petya can choose number 10 and Vasya can choose number 20. But for the game to be fair it is necessary to take 6 cards.

    【题目大意】

    给你n个数,保证n为偶数,问是否只有两种数且两种数数量相等

    【简单题解】

    记录每个数出现的次数且最多出现两个数以及两个数的数量即可

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #define max(a, b) ((a) > (b) ? (a) : (b))
     6 #define min(a, b) ((a) < (b) ? (a) : (b))
     7 
     8 const int INF = 0x3f3f3f3f;
     9 const int MAXN = 100 + 50;
    10 
    11 inline void swap(int &a, int &b)
    12 {
    13     int tmp = a;a = b;b = tmp;
    14 } 
    15 
    16 inline void read(int &x)
    17 {
    18     x = 0;char ch = getchar(), c = ch;
    19     while(ch < '0' || ch > '9')c = ch, ch = getchar();
    20     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    21     if(c == '-')x = -x;
    22 }
    23 
    24 int n,num[MAXN],cnt[MAXN];
    25 
    26 int tmp1, tmp2;
    27 
    28 int main()
    29 {
    30     read(n);
    31     for(register int i = 1;i <= n;++ i)
    32     {
    33         read(num[i]);
    34         cnt[num[i]] ++;
    35     }
    36     for(register int i = 1;i <= 110;++ i)
    37     {
    38         if(cnt[i] > 0 && !tmp1)
    39         {
    40             tmp1 = i;
    41         }
    42         else if(cnt[i] > 0 && !tmp2)
    43         {
    44             tmp2 = i;
    45         }
    46         else if(cnt[i] > 0 && tmp1 && tmp2)
    47         {
    48             printf("NO");
    49             return 0;
    50         }
    51     }
    52     if(tmp1 && tmp2 && cnt[tmp1] == cnt[tmp2])
    53         printf("YES
    %d %d", tmp1, tmp2);
    54     else
    55         printf("NO");
    56     return 0;
    57 }
    A

    考场上慌了,没判两个数是否相等,被hack了,最后1min改完交上。。但是200分没了T.不然就能进rank70了(唔)

    B. Polycarp and Letters
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Polycarp loves lowercase letters and dislikes uppercase ones. Once he got a string s consisting only of lowercase and uppercase Latin letters.

    Let A be a set of positions in the string. Let's call it pretty if following conditions are met:

    • letters on positions from A in the string are all distinct and lowercase;
    • there are no uppercase letters in the string which are situated between positions from A (i.e. there is no such j that s[j] is an uppercase letter, and a1 < j < a2 for some a1 and a2 from A).

    Write a program that will determine the maximum number of elements in a pretty set of positions.

    Input

    The first line contains a single integer n (1 ≤ n ≤ 200) — length of string s.

    The second line contains a string s consisting of lowercase and uppercase Latin letters.

    Output

    Print maximum number of elements in pretty set of positions for string s.

    Examples
    Input
    11
    aaaaBaabAbA
    Output
    2
    Input
    12
    zACaAbbaazzC
    Output
    3
    Input
    3
    ABC
    Output
    0
    Note

    In the first example the desired positions might be 6 and 8 or 7 and 8. Positions 6 and 7 contain letters 'a', position 8 contains letter 'b'. The pair of positions 1 and 8 is not suitable because there is an uppercase letter 'B' between these position.

    In the second example desired positions can be 7, 8 and 11. There are other ways to choose pretty set consisting of three elements.

    In the third example the given string s does not contain any lowercase letters, so the answer is 0.

    【题目大意】

    给你一个字符串,从中选择一些连续或不连续均可的字符,使得这些字符全是小写字符,且不连续的字符之间包含的字符不能有大写字幕

    【简单题解】

    枚举左端点,向右扫,记录一下出现过哪些字符和不重复字符的数量,所有左区间答案取max

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #define max(a, b) ((a) > (b) ? (a) : (b))
     6 #define min(a, b) ((a) < (b) ? (a) : (b))
     7 
     8 const int INF = 0x3f3f3f3f;
     9 const int MAXN = 2000 + 10;
    10 
    11 inline void swap(int &a, int &b)
    12 {
    13     int tmp = a;a = b;b = tmp;
    14 } 
    15 
    16 inline void read(int &x)
    17 {
    18     x = 0;char ch = getchar(), c = ch;
    19     while(ch < '0' || ch > '9')c = ch, ch = getchar();
    20     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    21     if(c == '-')x = -x;
    22 }
    23 
    24 int n, b[30], ans;
    25 char s[MAXN];
    26 
    27 int main()
    28 {
    29     read(n);
    30     scanf("%s", s + 1);
    31     int tmp = 0;
    32     for(register int i = 1;i <= n;++ i)
    33     {
    34         if(s[i] >= 'A' && s[i] <= 'Z')continue;
    35         memset(b, 0, sizeof(b));
    36         tmp = 0;
    37         for(register int j = i;j <= n;++ j)
    38         {
    39             if(s[j] >= 'A' && s[j] <= 'Z')break;
    40             if(!b[s[j] - 'a'])
    41                 b[s[j] - 'a'] = 1, ++ tmp; 
    42         } 
    43         ans = max(ans, tmp);
    44     }
    45     printf("%d", ans);
    46     return 0;
    47 }
    B
    C. Bus
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    A bus moves along the coordinate line Ox from the point x = 0 to the point x = a. After starting from the point x = 0, it reaches the point x = a, immediately turns back and then moves to the point x = 0. After returning to the point x = 0 it immediately goes back to the point x = a and so on. Thus, the bus moves from x = 0 to x = a and back. Moving from the point x = 0 to x = a or from the point x = a to x = 0 is called a bus journey. In total, the bus must make k journeys.

    The petrol tank of the bus can hold b liters of gasoline. To pass a single unit of distance the bus needs to spend exactly one liter of gasoline. The bus starts its first journey with a full petrol tank.

    There is a gas station in point x = f. This point is between points x = 0 and x = a. There are no other gas stations on the bus route. While passing by a gas station in either direction the bus can stop and completely refuel its tank. Thus, after stopping to refuel the tank will contain b liters of gasoline.

    What is the minimum number of times the bus needs to refuel at the point x = f to make k journeys? The first journey starts in the point x = 0.

    Input

    The first line contains four integers a, b, f, k (0 < f < a ≤ 106, 1 ≤ b ≤ 109, 1 ≤ k ≤ 104) — the endpoint of the first bus journey, the capacity of the fuel tank of the bus, the point where the gas station is located, and the required number of journeys.

    Output

    Print the minimum number of times the bus needs to refuel to make k journeys. If it is impossible for the bus to make k journeys, print -1.

    Examples
    Input
    6 9 2 4
    Output
    4
    Input
    6 10 2 4
    Output
    2
    Input
    6 5 4 3
    Output
    -1
    Note

    In the first example the bus needs to refuel during each journey.

    In the second example the bus can pass 10 units of distance without refueling. So the bus makes the whole first journey, passes 4 units of the distance of the second journey and arrives at the point with the gas station. Then it can refuel its tank, finish the second journey and pass 2 units of distance from the third journey. In this case, it will again arrive at the point with the gas station. Further, he can refill the tank up to 10 liters to finish the third journey and ride all the way of the fourth journey. At the end of the journey the tank will be empty.

    In the third example the bus can not make all 3 journeys because if it refuels during the second journey, the tanks will contain only 5 liters of gasoline, but the bus needs to pass 8 units of distance until next refueling.

    【题目大意】

    一个数轴,从0开始,a是终点。汽车从0走到a或者从a走到0叫做一个旅程。每走一个单位长度消耗一个汽油,初始有b点汽油。在f处有一个

    加油站,每次可以把油量变成b。问走k次旅程,最少需要加油多少次

    【简单题解】

    一半一半的模拟,具体细节参见代码

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #define max(a, b) ((a) > (b) ? (a) : (b))
     6 #define min(a, b) ((a) < (b) ? (a) : (b))
     7 
     8 const int INF = 0x3f3f3f3f;
     9 
    10 inline void swap(int &a, int &b)
    11 {
    12     int tmp = a;a = b;b = tmp;
    13 } 
    14 
    15 inline void read(int &x)
    16 {
    17     x = 0;char ch = getchar(), c = ch;
    18     while(ch < '0' || ch > '9')c = ch, ch = getchar();
    19     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    20     if(c == '-')x = -x;
    21 }
    22 
    23 int a,b,f,k,ans;
    24 
    25 int main()
    26 {
    27     read(a), read(b), read(f), read(k);
    28     int tmp = b;
    29     while(k)
    30     {
    31         tmp -= f;
    32         if(tmp < 0)
    33         {
    34             printf("-1");
    35             return 0;
    36         }
    37         if(tmp < 2 * (a - f) && k > 1)
    38         {
    39             tmp = b; 
    40             ++ ans;
    41         }
    42         else if(tmp <  (a - f)) 
    43         {
    44             ++ ans;
    45             tmp = b;
    46         }
    47         tmp -= (a - f);
    48         if(tmp < 0)
    49         {
    50             printf("-1");
    51             return 0;
    52         }
    53         -- k;
    54         if(!k)
    55         {
    56             printf("%d", ans);
    57             return 0;
    58         }
    59         
    60         tmp -= (a - f);
    61         if(tmp < 0)
    62         {
    63             printf("-1");
    64             return 0;
    65         }
    66         if(tmp < 2 * f && k > 1)
    67         {
    68             tmp = b;
    69             ++ ans;
    70         }
    71         else if(tmp < f)
    72         {
    73             tmp = b;
    74             ++ ans;
    75         }
    76         
    77         tmp -= f;
    78         if(tmp < 0)
    79         {
    80             printf("-1");
    81             return 0;
    82         }
    83         -- k;
    84     }
    85     printf("%d", ans);
    86     return 0;
    87 }
    C
    D. Make a Permutation!
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Ivan has an array consisting of n elements. Each of the elements is an integer from 1 to n.

    Recently Ivan learned about permutations and their lexicographical order. Now he wants to change (replace) minimum number of elements in his array in such a way that his array becomes a permutation (i.e. each of the integers from 1 to n was encountered in his array exactly once). If there are multiple ways to do it he wants to find the lexicographically minimal permutation among them.

    Thus minimizing the number of changes has the first priority, lexicographical minimizing has the second priority.

    In order to determine which of the two permutations is lexicographically smaller, we compare their first elements. If they are equal — compare the second, and so on. If we have two permutations x and y, then x is lexicographically smaller if xi < yi, where i is the first index in which the permutations x and y differ.

    Determine the array Ivan will obtain after performing all the changes.

    Input

    The first line contains an single integer n (2 ≤ n ≤ 200 000) — the number of elements in Ivan's array.

    The second line contains a sequence of integers a1, a2, ..., an (1 ≤ ai ≤ n) — the description of Ivan's array.

    Output

    In the first line print q — the minimum number of elements that need to be changed in Ivan's array in order to make his array a permutation. In the second line, print the lexicographically minimal permutation which can be obtained from array with q changes.

    Examples
    Input
    4
    3 2 2 3
    Output
    2
    1 2 4 3
    Input
    6
    4 5 6 3 2 1
    Output
    0
    4 5 6 3 2 1
    Input
    10
    6 8 4 6 7 1 6 3 4 5
    Output
    3
    2 8 4 6 7 1 9 3 10 5
    Note

    In the first example Ivan needs to replace number three in position 1 with number one, and number two in position 3 with number four. Then he will get a permutation [1, 2, 4, 3] with only two changed numbers — this permutation is lexicographically minimal among all suitable.

    In the second example Ivan does not need to change anything because his array already is a permutation

    【题目大意】

    给你n个数组成的数列,让你替换其中t个数,使得这个数列是一个关于n的排列(即n个数是1,2,3...n,顺序任意)
    要求首先满足t最小;t相等时,替换后数列字典序最小

    【简单题解】

    首先记录哪一些数还没有出现过,并记录每个数出现了多少次,从前往后扫

    扫到某个数字出现次数>1 ,如果他的字典序比最小的未出,那么

    就不替换,且下一次扫到这个数字一定要替换他;否则就用p

    替换掉他,并继续增大p使其变为第一个未出现的数字。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #define max(a, b) ((a) > (b) ? (a) : (b))
     6 #define min(a, b) ((a) < (b) ? (a) : (b))
     7 
     8 const int INF = 0x3f3f3f3f;
     9 const int MAXN = 300000 + 10;
    10 
    11 inline void swap(int &a, int &b)
    12 {
    13     int tmp = a;a = b;b = tmp;
    14 } 
    15 
    16 inline void read(int &x)
    17 {
    18     x = 0;char ch = getchar(), c = ch;
    19     while(ch < '0' || ch > '9')c = ch, ch = getchar();
    20     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    21     if(c == '-')x = -x;
    22 }
    23 
    24 int n, num[MAXN], b[MAXN], bb[MAXN], flag[MAXN], ans;
    25 
    26 int main()
    27 {
    28     read(n);
    29     for(register int i = 1;i <= n;++ i)
    30     {
    31         read(num[i]);
    32         if(num[i] <= n)
    33             b[num[i]] = 1, ++bb[num[i]];
    34     }
    35     register int p = 1;
    36     while(b[p]) ++ p;
    37     for(register int i = 1;i <= n;++ i)
    38     {
    39         if(flag[num[i]])
    40         {
    41             -- bb[num[i]];
    42             num[i] = p;
    43             ++ ans;
    44             b[p] = 1;
    45             while(b[p]) ++ p;
    46         }
    47         else if(bb[num[i]] > 1)
    48         {
    49             -- bb[num[i]];
    50             if(num[i] < p)
    51             {
    52                 flag[num[i]] = 1;
    53                 continue;
    54             }
    55             num[i] = p;
    56             ++ ans;
    57             b[p] = 1;
    58             while(b[p]) ++ p;
    59         }
    60     }
    61     printf("%d
    ", ans);
    62     for(register int i = 1;i <= n;++ i)
    63         printf("%d ", num[i]);
    64     return 0;
    65 }
    D
    E. Fire
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Polycarp is in really serious trouble — his house is on fire! It's time to save the most valuable items. Polycarp estimated that it would take ti seconds to save i-th item. In addition, for each item, he estimated the value of di — the moment after which the item i will be completely burned and will no longer be valuable for him at all. In particular, if ti ≥ di, then i-th item cannot be saved.

    Given the values pi for each of the items, find a set of items that Polycarp can save such that the total value of this items is maximum possible. Polycarp saves the items one after another. For example, if he takes item a first, and then item b, then the item a will be saved in ta seconds, and the item b — in ta + tb seconds after fire started.

    Input

    The first line contains a single integer n (1 ≤ n ≤ 100) — the number of items in Polycarp's house.

    Each of the following n lines contains three integers ti, di, pi (1 ≤ ti ≤ 20, 1 ≤ di ≤ 2 000, 1 ≤ pi ≤ 20) — the time needed to save the item i, the time after which the item i will burn completely and the value of item i.

    Output

    In the first line print the maximum possible total value of the set of saved items. In the second line print one integer m — the number of items in the desired set. In the third line print m distinct integers — numbers of the saved items in the order Polycarp saves them. Items are 1-indexed in the same order in which they appear in the input. If there are several answers, print any of them.

    Examples
    Input
    3
    3 7 4
    2 6 5
    3 7 6
    Output
    11
    2
    2 3
    Input
    2
    5 6 1
    3 3 5
    Output
    1
    1
    1
    Note

    In the first example Polycarp will have time to save any two items, but in order to maximize the total value of the saved items, he must save the second and the third item. For example, he can firstly save the third item in 3 seconds, and then save the second item in another 2 seconds. Thus, the total value of the saved items will be 6 + 5 = 11.

    In the second example Polycarp can save only the first item, since even if he immediately starts saving the second item, he can save it in 3 seconds, but this item will already be completely burned by this time.

    【题目大意】

    有一些东西在火场里。拯救他需要时间t,他在时间d会被焚烧完(拯救过程也计时)。如果能救出来,会获得
    价值v,问最大价值

    【简单题解】

    一开始想的裸Dp:
    dp[i][j]表示前i个物品,时间j的最大价值,
    像01背包那样转移,记录方案即可
    手出一组数据发现不对
    然后按d从小到大排序
    输出时按照拯救的先后顺序(我没看见,误打误撞A了)
    显然法可以证明(捂脸)
    然后一遍过了
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <cstring>
     6 #define max(a, b) ((a) > (b) ? (a) : (b))
     7 #define min(a, b) ((a) < (b) ? (a) : (b))
     8 
     9 const int INF = 0x3f3f3f3f;
    10 const int MAXN = 100 + 10;
    11 const int MAXD = 2000 + 10;
    12 
    13 inline void swap(int &a, int &b)
    14 {
    15     int tmp = a;a = b;b = tmp;
    16 } 
    17 
    18 inline void read(int &x)
    19 {
    20     x = 0;char ch = getchar(), c = ch;
    21     while(ch < '0' || ch > '9')c = ch, ch = getchar();
    22     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    23     if(c == '-')x = -x;
    24 }
    25 
    26 int n,cnt[MAXN],dp[MAXN][MAXD],t[MAXN],p[MAXN],d[MAXN],ma, fangan1[MAXN][MAXD], fangan2[MAXN][MAXD], flag[MAXN][MAXD], ans[MAXN], tot;
    27 
    28 void dfs(int num1, int num2)
    29 {
    30     if(num1 == -1 || num2 == -1 || num1 == 0 || num2 == 0)return;
    31     if(flag[num1][num2])
    32         ans[++tot] = num1;
    33     dfs(fangan1[num1][num2], fangan2[num1][num2]);
    34 }
    35 
    36 bool cmp(int a, int b)
    37 {
    38     return d[a] < d[b]; 
    39 }
    40 
    41 int main()
    42 {
    43     read(n);
    44     for(register int i = 1;i <= n;++ i)
    45         read(t[i]), read(d[i]), read(p[i]), ma = max(ma, d[i]), cnt[i] = i;
    46     memset(fangan1, -1, sizeof(fangan1));
    47     memset(fangan2, -1, sizeof(fangan2));
    48     memset(flag, -1, sizeof(flag));
    49     std::sort(cnt + 1, cnt + 1 + n, cmp);
    50     for(register int ii = 1;ii <= n;++ ii)
    51         for(register int j = 1;j <= ma;++ j)
    52         {
    53             dp[cnt[ii]][j] = dp[cnt[ii - 1]][j];
    54             fangan1[cnt[ii]][j] = cnt[ii - 1];
    55             fangan2[cnt[ii]][j] = j;
    56             flag[cnt[ii]][j] = 0;
    57             for(register int k = 0;k <= ma;++ k)
    58             {
    59                 if(k + t[cnt[ii]] > j || k + t[cnt[ii]] >= d[cnt[ii]])continue;
    60                 if(dp[cnt[ii]][j] < dp[cnt[ii - 1]][k] + p[cnt[ii]])
    61                 {
    62                     dp[cnt[ii]][j] = dp[cnt[ii - 1]][k] + p[cnt[ii]];
    63                     fangan1[cnt[ii]][j] = cnt[ii - 1];
    64                     fangan2[cnt[ii]][j] = k;
    65                     flag[cnt[ii]][j] = 1;
    66                 }
    67             }
    68         }
    69     printf("%d
    ", dp[cnt[n]][ma]);
    70     dfs(cnt[n], ma);
    71     printf("%d
    ", tot);
    72     for(register int i = tot;i >= 1;-- i)
    73         printf("%d ", ans[i]);
    74     return 0;
    75 }
    E

    F题读了十分钟读完题:woc这题意什么鬼。。

    hack(害)人去了

    没hack到反被人hackA题

    最后一分钟改完

    废了200分

    T.T

    最终rank80+

    上次还是rank800+。。

    人的一生啊,不但要有个人的奋斗,还要考虑到历史的进程。。。

     ”

    F. Cities Excursions
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    There are n cities in Berland. Some pairs of them are connected with m directed roads. One can use only these roads to move from one city to another. There are no roads that connect a city to itself. For each pair of cities (x, y) there is at most one road from x to y.

    A path from city s to city t is a sequence of cities p1, p2, ... , pk, where p1 = s, pk = t, and there is a road from city pi to city pi + 1 for each i from 1 to k - 1. The path can pass multiple times through each city except t. It can't pass through t more than once.

    A path p from s to t is ideal if it is the lexicographically minimal such path. In other words, p is ideal path from s to t if for any other path q from s to t pi < qi, where i is the minimum integer such that pi ≠ qi.

    There is a tourist agency in the country that offers q unusual excursions: the j-th excursion starts at city sj and ends in city tj.

    For each pair sj, tj help the agency to study the ideal path from sj to tj. Note that it is possible that there is no ideal path from sj to tj. This is possible due to two reasons:

    • there is no path from sj to tj;
    • there are paths from sj to tj, but for every such path p there is another path q from sj to tj, such that pi > qi, where i is the minimum integer for which pi ≠ qi.

    The agency would like to know for the ideal path from sj to tj the kj-th city in that path (on the way from sj to tj).

    For each triple sj, tj, kj (1 ≤ j ≤ q) find if there is an ideal path from sj to tj and print the kj-th city in that path, if there is any.

    Input

    The first line contains three integers n, m and q (2 ≤ n ≤ 3000,0 ≤ m ≤ 3000, 1 ≤ q ≤ 4·105) — the number of cities, the number of roads and the number of excursions.

    Each of the next m lines contains two integers xi and yi (1 ≤ xi, yi ≤ n, xi ≠ yi), denoting that the i-th road goes from city xi to city yi. All roads are one-directional. There can't be more than one road in each direction between two cities.

    Each of the next q lines contains three integers sj, tj and kj (1 ≤ sj, tj ≤ n, sj ≠ tj, 1 ≤ kj ≤ 3000).

    Output

    In the j-th line print the city that is the kj-th in the ideal path from sj to tj. If there is no ideal path from sj to tj, or the integer kj is greater than the length of this path, print the string '-1' (without quotes) in the j-th line.

    Example
    Input
    7 7 5
    1 2
    2 3
    1 3
    3 4
    4 5
    5 3
    4 6
    1 4 2
    2 6 1
    1 7 3
    1 3 2
    1 3 5
    Output
    2
    -1
    -1
    2
    -1
    【题目大意】

    有一张n个点m条边的有向图和q次询问每次询问包含s,t,k,要你输出字典序最小且只能经过一次t(其他点可

    经过若干次)的路径p1,p2,p3...pa,p1 = s, pa = t中pk是多少

    【简单题解】

    考虑倍增。
    p[i][j][k]表示从i到j,i的标号为0,第2^k个节点,即把i看做标号0,往前跳2^k步
    reach[i][j]表示i,j是否能到达
    先dfs处理reach[i][j]
    然后用reach[i][j]去更新p[i][j][0]
    然后用p[i][j][0]去做p
    然后对于每个s,t,k
    因为我们p把i当做零,所以k要- 1
    倍增跳即可
    注意可能存在一个字典序很小的环导致无限走这个环,这个时候无解
    两点还可能无法到达,这个时候也无解
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 #include <cstring>
      6 #define max(a, b) ((a) > (b) ? (a) : (b))
      7 #define min(a, b) ((a) < (b) ? (a) : (b))
      8 
      9 const short int MAXN = 3000 + 1;
     10 const short int MAXLOG = 14; 
     11 const short int INF = 0x3f3f;
     12 
     13 inline void swap(short int &a, short int &b)
     14 {
     15     int tmp = a;a = b;b = tmp;
     16 } 
     17 
     18 inline void read(short int &x)
     19 {
     20     x = 0;char ch = getchar(), c = ch;
     21     while(ch < '0' || ch > '9')c = ch, ch = getchar();
     22     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
     23     if(c == '-')x = -x;
     24 }
     25 inline void read(int &x)
     26 {
     27     x = 0;char ch = getchar(), c = ch;
     28     while(ch < '0' || ch > '9')c = ch, ch = getchar();
     29     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
     30     if(c == '-')x = -x;
     31 }
     32 struct Edge
     33 {
     34     short int v,nxt;
     35     Edge(short int _v, short int _nxt){v = _v;nxt = _nxt;}
     36     Edge(){}
     37 }edge[MAXN];
     38 short int head[MAXN], cnt;
     39 inline void insert(short int a, short int b)
     40 {
     41     edge[++cnt] = Edge(b,head[a]);
     42     head[a] = cnt; 
     43 }
     44 
     45 short int n,m,p[MAXLOG][MAXN][MAXN],tmp1,tmp2;
     46 int q;
     47 bool reach[MAXN][MAXN];
     48 
     49 void dfs(short int u, short int v)
     50 {
     51     reach[u][v] = 1;
     52     for(register short int pos = head[v];pos;pos = edge[pos].nxt)
     53     {
     54         short int vv =edge[pos].v;
     55         if(!reach[u][vv])dfs(u, vv);
     56     }
     57 }
     58 
     59 int main()
     60 {
     61     read(n), read(m), read(q);
     62     for(register short int i = 1;i <= m; ++ i)
     63     {
     64         read(tmp1), read(tmp2);
     65         insert(tmp1, tmp2);    
     66     }
     67     for(register short int i = 1;i <= n;++ i)
     68         dfs(i,i);
     69     for(register short int i = 1;i <= n;++ i)
     70         for(short int j = 1;j <= n;++ j)
     71         {
     72             p[0][i][j] = INF;
     73             if(i == j)p[0][i][j] = 0;
     74             else 
     75             {
     76                 for(short int pos = head[i];pos;pos = edge[pos].nxt)
     77                 {
     78                     short int v = edge[pos].v;
     79                     if(reach[v][j] && v < p[0][i][j])p[0][i][j] = v;
     80                 }
     81             }
     82             if(p[0][i][j] == INF)p[0][i][j] = 0;
     83         }
     84     for(short int i = 1;i < MAXLOG;++ i)
     85         for(register short int j = 1;j <= n;++ j)
     86             for(register short int k = 1;k <= n;++ k)
     87                 p[i][j][k] = p[i - 1][p[i - 1][j][k]][k];
     88     short int s,t,k;
     89     for(;q;--q)
     90     {
     91         read(s), read(t), read(k);
     92         -- k;
     93         short int ans;
     94         if(p[MAXLOG - 1][s][t])ans = -1;
     95         else if(!p[0][s][t])ans = -1;
     96         else
     97         {
     98             ans = s;
     99             for(register short int i = MAXLOG - 1;i >= 0;-- i)
    100                 if(k & (1 << i))
    101                     ans = p[i][ans][t];
    102         }
    103         if(!ans) ans = -1; 
    104         printf("%d
    ", ans);
    105     } 
    106     return 0;
    107 }
    F
  • 相关阅读:
    ulimit
    python3.7安装Scrapy
    用VS2013写第一个汇编语言程序
    螺旋矩阵问题
    Java Web Pro与apache tomcat初始化关联
    记一次m3u8多个视频文件合并为整体法四(未加密)
    记一次m3u8多个视频文件合并为整体法三(未加密)
    记一次m3u8多个视频文件合并为整体法二(未加密)
    记将m3u8多个视频文件合并为整体法一(未加密)
    c++给定字符分割
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7594237.html
Copyright © 2011-2022 走看看