码迷,mamicode.com
首页 > 编程语言 > 详细

POJ3687 反向拓扑排序

时间:2018-08-29 21:27:22      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:--   mis   cat   tab   def   vector   zh-cn   script   pac   

Labeling Balls
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 16032   Accepted: 4713

Description

Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to N in such a way that:

  1. No two balls share the same label.
  2. The labeling satisfies several constrains like "The ball labeled with a is lighter than the one labeled with b".

Can you help windy to find a solution?

Input

The first line of input is the number of test case. The first line of each test case contains two integers, N (1 ≤ N ≤ 200) and M (0 ≤ M ≤ 40,000). The next M line each contain two integers a and bindicating the ball labeled with a must be lighter than the one labeled with b. (1 ≤ a, b ≤ N) There is a blank line before each test case.

Output

For each test case output on a single line the balls‘ weights from label 1 to label N. If several solutions exist, you should output the one with the smallest weight for label 1, then with the smallest weight for label 2, then with the smallest weight for label 3 and so on... If no solution exists, output -1 instead.

Sample Input

5

4 0

4 1
1 1

4 2
1 2
2 1

4 1
2 1

4 1
3 2

Sample Output

1 2 3 4
-1
-1
2 1 3 4
1 3 2 4

Source

 

题意:

给定N个球,编号分别是1-N,重量也是1-N,任意两个球的编号和重量不相等。

给定一些约束:类似编号为a的球比编号为b的球轻,要求输出的答案必须让编号为1的球重量尽量轻,接着是编号为2的球重量尽量轻,一直到编号为N的球尽量轻。

思路:

原命题:编号小的球重量尽量轻。   

逆否命题:重量大的球编号尽量大,逆向拓扑排序即可。

PS:数据存在重边,自环等。。

代码:

 1 #include"bits/stdc++.h"
 2 
 3 #define db double
 4 #define ll long long
 5 #define vl vector<ll>
 6 #define ci(x) scanf("%d",&x)
 7 #define cd(x) scanf("%lf",&x)
 8 #define cl(x) scanf("%lld",&x)
 9 #define pi(x) printf("%d\n",x)
10 #define pd(x) printf("%f\n",x)
11 #define pl(x) printf("%lld\n",x)
12 #define rep(i, a, n) for (int i=a;i<n;i++)
13 #define per(i, a, n) for (int i=n-1;i>=a;i--)
14 #define fi first
15 #define se second
16 using namespace std;
17 typedef pair<int, int> pii;
18 const int N   = 1e5 + 5;
19 const int mod = 1e9 + 7;
20 const int MOD = 998244353;
21 const db  PI  = acos(-1.0);
22 const db eps  = 1e-10;
23 const int inf = 0x3f3f3f3f;
24 const ll INF  = 0x3fffffffffffffff;
25 
26 int n,m,cnt;
27 bool mp[205][205];
28 int du[N],head[N];
29 int a[205];
30 struct P{int to,nxt;}e[N];
31 void add(int u,int v){
32     e[cnt].to=v;
33     e[cnt].nxt=head[u];
34     head[u]=cnt++;
35 }
36 void topsort()
37 {
38     int k=n;
39     priority_queue<int>q;
40     for(int i=1;i<=n;i++) if(!du[i]) q.push(i);
41     while(!q.empty())
42     {
43         int tmp=q.top();
44         q.pop();
45         a[tmp]=k--;
46         for(int i=head[tmp];~i;i=e[i].nxt){
47             int v=e[i].to;
48             du[v]--;
49             if(!du[v]) q.push(v);
50         }
51     }
52     if(k!=0) printf("-1\n");
53     else
54     {
55         for(int i=1;i<=n;i++)
56             printf("%d%c",a[i],i==n?\n: );
57     }
58 }
59 void init()
60 {
61     memset(mp,0,sizeof(mp));
62     memset(a,0,sizeof(a));
63     memset(head,-1,sizeof(head));
64     memset(du,0,sizeof(du));
65     cnt=0;
66 }
67 int main()
68 {
69     int t;
70     ci(t);
71     while(t--)
72     {
73         init();
74         scanf("%d%d",&n,&m);
75         while(m--)
76         {
77             int x,y;
78             scanf("%d%d",&x,&y);
79             if(mp[x][y]==1) continue;
80             mp[x][y]=1,add(y,x);//反向边
81             du[x]++;
82         }
83         topsort();
84     }
85     return 0;
86 }

 

POJ3687 反向拓扑排序

标签:--   mis   cat   tab   def   vector   zh-cn   script   pac   

原文地址:https://www.cnblogs.com/mj-liylho/p/9556648.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!