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 }

 

posted on 2015-08-18 17:37  张济  阅读(225)  评论(0编辑  收藏  举报

导航