Labeling Balls

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 }
View Code
原文地址:https://www.cnblogs.com/chujian123/p/3365237.html