POJ3687 反向拓扑排序
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:
- No two balls share the same label.
- 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 }