poj3687:http://poj.org/problem?id=3687
题意:有N个重量1到N的点,把这N个点涂色,要求在一定的约束下颜色a必须比颜色b要轻,如果有多种选择则让重量最小的对应编号1,然后剩下中重量最小的给编号2,一次类推
题解:逆向建图,这样取出来的就是最后选择的点,并标上最大重量,把邻接点入度为0的加入到优先队列中,然后取编号最大的,为的是使得留着编号最小的给重量最大的
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 const int maxn = 202; 7 int edge[maxn][maxn]; 8 int cnt[maxn]; 9 int ans[maxn]; 10 int tot; 11 int toporder(int n) 12 { 13 priority_queue <int> q; 14 int i,j,k; 15 for(i=1;i<=n;i++) 16 if(cnt[i] == 0) q.push(i); 17 for(i=1;i<=n;i++) 18 if(q.empty()) return 0; 19 else 20 { 21 j = q.top();q.pop(); 22 ans[j] = tot--; 23 for(k=1;k<=n;k++) 24 if(edge[j][k] && (--cnt[k]) == 0) q.push(k); 25 } 26 return 1; 27 } 28 int main () 29 { 30 int n,m,t,i,u,v; 31 scanf("%d",&t); 32 while(t--) 33 { 34 scanf("%d%d",&n,&m); 35 memset(edge,0,sizeof(edge)); 36 memset(cnt,0,sizeof(cnt)); 37 tot = n; 38 for(i=0;i<m;i++) 39 { 40 scanf("%d%d",&u,&v); 41 if(edge[v][u] == 0) cnt[u]++; 42 edge[v][u] = 1; 43 } 44 if(toporder(n)) 45 { 46 for(i=1;i<=n;i++) 47 if(i == n)printf("%d ",ans[i]); 48 else printf("%d ",ans[i]); 49 } 50 else printf("-1 "); 51 } 52 return 0; 53 }