UVA - 12263 Rankings 模拟(拓扑排序)
题意:1~n这n个数,给你一个初始的顺序,再告诉你那两个数的大小关系发生了变化,求变化后的 顺序,不存在则输出IMPOSSIBLE
思路:这题很遗憾没在比赛的时候过掉,结束后加了一行就AC了。题目真的不难,我就是根据原顺序和变化得到任意两个数之间的大小关系。然后枚举变化后的这些数对,用构造法构造一个合法的序列,最后再和原顺序进行不重复的合并。两个数组,两个指针,合并的时候未发生变化的当前数若大于变化的当前数,则输出原数,否则输出变化后的数,并将对应数组指针后移。再对得到的新顺序进行合法判断,若大小关系和要求的完全一致,则输出答案,否则无解。
这题还有更简单的拓扑排序做法,我正在研究,稍后更新。
1 #pragma comment(linker, "/STACK:1000000000") 2 #include <bits/stdc++.h> 3 #define LL long long 4 #define INF 0x3f3f3f3f 5 #define IN freopen("E.in","r",stdin); 6 #define OUT freopen("out.txt", "w", stdout); 7 using namespace std; 8 #define MAXN 505 9 #define MAXM 25005 10 int s[MAXM], t[MAXM]; 11 int a[MAXN], b[MAXN], pos[MAXN], c[MAXN]; 12 bool dayu[MAXN][MAXN], res[MAXN][MAXN], u[MAXN][MAXN]; 13 bool vis[MAXN]; 14 int main() 15 { 16 int T; 17 scanf("%d", &T); 18 int cas = 1; 19 while(T--){ 20 cas++; 21 int n; 22 scanf("%d", &n); 23 for(int i = 1; i <= n; i++){ 24 scanf("%d", &a[i]); 25 } 26 memset(dayu, 0, sizeof(dayu)); 27 memset(vis, 0, sizeof(vis)); 28 memset(b, 0, sizeof(b)); 29 for(int i = 1; i <= n; i++){ 30 for(int j = i + 1; j <= n; j++){ 31 dayu[a[i]][a[j]] = true; 32 } 33 } 34 int m; 35 scanf("%d", &m); 36 memset(u, 0, sizeof(u)); 37 for(int i = 1; i <= m; i++){ 38 scanf("%d%d", &s[i], &t[i]); 39 if(u[s[i]][t[i]]) continue; 40 u[s[i]][t[i]] = true; 41 dayu[s[i]][t[i]] = !dayu[s[i]][t[i]]; 42 dayu[t[i]][s[i]] = !dayu[t[i]][s[i]]; 43 } 44 int x, y; 45 int p = 0; 46 bool noans = false; 47 for(int i = 1; i <= m; i++){ 48 if(dayu[s[i]][t[i]]){ 49 x = t[i]; 50 y = s[i]; 51 }else{ 52 x = s[i]; 53 y = t[i]; 54 } 55 if(!vis[x]){ 56 vis[x] = true; 57 int j = p; 58 if(p == 0){ 59 b[++p] = x; 60 } 61 else{ 62 while(j >= 0 && dayu[x][b[j]]){ 63 j--; 64 } 65 for(int k = p; k > j; k--){ 66 pos[b[k]]++; 67 b[k + 1] = b[k]; 68 } 69 b[j + 1] = x; 70 p++; 71 } 72 pos[x] = j + 1; 73 } 74 if(!vis[y]){ 75 vis[y] = true; 76 int j = pos[x] - 1; 77 while(j >= 0 && dayu[y][b[j]]){ 78 j--; 79 } 80 for(int k = p; k > j; k--){ 81 pos[b[k]]++; 82 b[k + 1] = b[k]; 83 } 84 p++; 85 b[j + 1] = y; 86 pos[y] = j + 1; 87 } 88 } 89 int j = 1; 90 memset(pos, 0, sizeof(pos)); 91 for(int i = 1; i <= n; i++){ 92 if(vis[a[i]]){ 93 c[i] = b[j++]; 94 } 95 else{ 96 if(dayu[a[i]][b[j]] || j > p){ 97 c[i] = a[i]; 98 } 99 else{ 100 c[i] = b[j++]; 101 } 102 } 103 pos[c[i]] = i; 104 } 105 memset(res, 0, sizeof(res)); 106 for(int i = 1; i <= n; i++){ 107 for(int j = i + 1; j <= n; j++){ 108 res[c[i]][c[j]] = true; 109 } 110 } 111 for(int i = 1; i <= n; i++){ 112 for(int j = 1; j <= n; j++){ 113 if(res[i][j] != dayu[i][j]){ 114 noans = true; 115 break; 116 } 117 } 118 if(noans){ 119 break; 120 } 121 } 122 if(noans){ 123 printf("IMPOSSIBLE\n"); 124 continue; 125 } 126 for(int i = 1; i < n; i++){ 127 printf("%d ", c[i]); 128 } 129 printf("%d\n", c[n]); 130 } 131 return 0; 132 }