hdu 1811 Rank of Tetris(拓扑,并查集)
题意:略
分析:排序先按rating,若相同,则按rp。考虑到每个人的rp均不同,所以rating相同的人必然可以排序。那么只需要考虑rating不同的集合了。
大小关系可以用有向边表示,而大小关系的传递可以用拓扑排序来呈现。
接着就要分析,三种结果对应的情况了。
很明显,ok要求拓扑出来的必须是一条链,一旦有分支,分支处的两个(或多个)点的大小关系就不明确,也就是条件不足=>uncertain。
而矛盾conflict有两种情况:1、更改关系0=1,0>1;2、自相矛盾,即成环,0>1,0<1。
注意:在条件不足和矛盾同时发生时,要求输出的是矛盾conflict。
这里要注意,拓扑排序是可以判环的:只要完成拓扑后,发现还有点没有加入队列,那么就说明他们之间成环。若不成环,必然可以把所有点加入队列。
学习了vector的find函数
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<queue> 5 #include<algorithm> 6 using namespace std; 7 8 const int MAXN=11111; 9 10 struct Edge{ 11 int x,y; 12 char op; 13 }edge[MAXN<<1]; 14 15 vector<int>G[MAXN]; 16 queue<int>q; 17 int in[MAXN],f[MAXN]; 18 int inq[MAXN]; 19 20 void init(int n) 21 { 22 for(int i=0;i<n;i++) 23 f[i]=i; 24 25 memset(in,0,sizeof(in)); 26 27 for(int i=0;i<n;i++) 28 G[i].clear(); 29 } 30 31 int Find(int x) 32 { 33 return f[x]==x?x:f[x]=Find(f[x]); 34 } 35 36 int top(int n) 37 { 38 int flog=1; 39 while(!q.empty()) 40 q.pop(); 41 memset(inq,0,sizeof(inq));//判入队 42 43 for(int i=0;i<n;i++) 44 { 45 int x=Find(i); 46 if(x!=i)//忽略所有集合中除根以外的点 47 inq[i]=1; 48 else if(in[x]==0){ 49 q.push(x); 50 inq[x]=1; 51 } 52 } 53 if(q.empty())//队空,成环,冲突 54 return -1; 55 while(!q.empty()) 56 { 57 if(q.size()>=2)//多叉,不分先后,条件不足 58 flog=0; 59 60 int u=q.front();q.pop(); 61 int sz=G[u].size(); 62 for(int i=0;i<sz;i++) 63 { 64 int v=G[u][i]; 65 in[v]--; 66 if(in[v]==0){ 67 if(inq[v])//成环,冲突 68 return -1; 69 else { 70 q.push(v); 71 inq[v]=1; 72 } 73 } 74 } 75 } 76 for(int i=0;i<n;i++) 77 if(!inq[i])//不能全部拓扑,成环,冲突 78 return -1; 79 return flog; 80 } 81 82 int main() 83 { 84 int n,m; 85 while(~scanf("%d%d",&n,&m)) 86 { 87 int flog=1; 88 init(n); 89 for(int i=0;i<m;i++) 90 { 91 scanf("%d %c %d",&edge[i].x,&edge[i].op,&edge[i].y); 92 if(edge[i].op=='='){ 93 int a=Find(edge[i].x); 94 int b=Find(edge[i].y); 95 f[a]=b; 96 } 97 } 98 for(int i=0;i<m;i++) 99 { 100 if(edge[i].op=='=') 101 continue; 102 103 int a=Find(edge[i].x);//所有处理都是对集合的根做操作 104 int b=Find(edge[i].y); 105 if(a==b) 106 flog=-1; 107 if(flog==-1) 108 break; 109 110 if(edge[i].op=='<'){ 111 if(find(G[b].begin(),G[b].end(),a)==G[b].end()){//去重,长知识了 112 G[b].push_back(a); 113 in[a]++; 114 } 115 }else{ 116 if(find(G[a].begin(),G[a].end(),b)==G[a].end()){ 117 G[a].push_back(b); 118 in[b]++; 119 } 120 } 121 } 122 if(flog==-1){ 123 printf("CONFLICT\n"); 124 continue; 125 } 126 flog=top(n); 127 if(flog==-1) 128 printf("CONFLICT\n"); 129 else if(flog==0) 130 printf("UNCERTAIN\n"); 131 else 132 printf("OK\n"); 133 } 134 return 0; 135 } 136 /* 137 4 3 138 0 < 1 139 1 < 2 140 2 < 0 141 142 4 3 143 0 > 1 144 1 < 2 145 0 > 2 146 147 4 3 148 1 = 2 149 0 < 1 150 3 > 2 151 152 4 3 153 1 = 2 154 0 < 1 155 0 > 2 156 157 3 3 158 1 = 2 159 2 = 0 160 1 > 2 161 162 3 1 163 1 < 2 164 */