暑假集训Day8 A (拓扑排序判环)
作者:互联网
原题链接在这里:Problem - A - Codeforces
首先还是判断是否有环,如果没有环的话直接输出1就行了,不得不说拓扑排序比tarjan判环的码量小了很多
然后就是一个环的性质,我们把环展成一条链,这链上面的点必定不是单调的,因为环必然会有一个点指向前面的点,所以这是显然的,根据这个性质对环的边进行染色就行了
1 #include "bits/stdc++.h" 2 using namespace std; 3 const int MAX=5005; 4 int n,m; 5 struct Node{ 6 int v,no; 7 }a[MAX][MAX]; 8 int cnt[MAX]; 9 int ii[MAX],ans[MAX]; 10 bool topu(){ 11 int i,j,zt,an=0; 12 queue <int> q; 13 while (!q.empty()) q.pop(); 14 for (i=1;i<=n;i++) 15 if (ii[i]==0) 16 q.push(i),an++; 17 while (!q.empty()){ 18 zt=q.front();q.pop(); 19 //cout<<zt<<endl; 20 for (i=1;i<=cnt[zt];i++){ 21 //cout<<zt<<' '<<a[zt][i].v<<endl; 22 if (ii[a[zt][i].v]){ 23 ii[a[zt][i].v]--; 24 if (ii[a[zt][i].v]==0) q.push(a[zt][i].v),an++; 25 } 26 } 27 } 28 return (an==n); 29 } 30 int main(){ 31 int i,j,u,v; 32 scanf("%d%d",&n,&m); 33 memset(cnt,0,sizeof(cnt)); 34 memset(ii,0,sizeof(ii)); 35 for (i=1;i<=m;i++){ 36 scanf("%d%d",&u,&v); 37 a[u][++cnt[u]].v=v; 38 a[u][cnt[u]].no=i; 39 ii[v]++; 40 } 41 if (topu()){ 42 printf("1\n"); 43 for (i=1;i<=m;i++) printf("1 "); 44 return 0; 45 } 46 memset(ans,0,sizeof(ans)); 47 for (i=1;i<=n;i++) 48 for (j=1;j<=cnt[i];j++) 49 if (!ans[a[i][j].no]){ 50 if (a[i][j].v<i) ans[a[i][j].no]=1; 51 else ans[a[i][j].no]=2; 52 } 53 printf("2\n"); 54 for (i=1;i<=m;i++) printf("%d ",ans[i]); 55 return 0; 56 }
标签:std,判环,Day8,int,MAX,拓扑,排序,集训 来源: https://www.cnblogs.com/keximeiruguo/p/15041647.html