https://vjudge.net/problem/CodeForces-1217Dios
請給一個有向圖着色,使得沒有一個環只有一個顏色,您須要最小化使用顏色的數量。c++
由於是有向圖,每一個環兩個顏色就能夠知足了。因此最大爲2,最小爲1。spa
法1 dfs:.net
用dfs判斷有向圖的環,每次把構成環的最後那條邊染成2,其他染成1。blog
法2 拓撲排序:排序
容易發現,對於一個有向圖,若是成環那麼點的序號必不是單調的,由於最後的那個點又會連回起始點。ci
因此咱們把u<v染成1,u>v染成2,而後拓撲排序判環,若是有環那麼就輸出染色方案,不然全輸出1。get
法1:it
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=5e3+5; const int mod=1e9+7; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) vector<int> g[N]; int e[N][N],vis[N],col[N],gg,in[N]; void dfs(int u) { int sz=g[u].size(); in[u]=1; for(int i=0;i<sz;i++) { int v=g[u][i]; if(!vis[v]) { vis[v]=1; col[e[u][v]]=1; dfs(v); } else if(in[v]) { col[e[u][v]]=2; gg=1; } else { col[e[u][v]]=1; } } in[u]=0; } int main() { std::ios::sync_with_stdio(false); int n,m; while(cin>>n>>m) { memset(vis,0,sizeof(vis)); for(int i=1;i<=m;i++) { int u,v; cin>>u>>v; g[u].push_back(v); e[u][v]=i; } gg=0; for(int i=1;i<=n;i++) { if(!vis[i]) { // col[i]=1; vis[i]=1; dfs(i); } } if(!gg) { cout<<1<<endl; for(int i=1;i<=m;i++) cout<<1<<" "; cout<<endl; } else { cout<<2<<endl; for(int i=1;i<=m;i++) cout<<col[i]<<" "; cout<<endl; } } return 0; }
法2:io
#include<bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define ll long long const int N=200005; const int mod=1e9+7; const double eps=1e-8; const double PI = acos(-1.0); #define lowbit(x) (x&(-x)) vector<int> g[N]; int col[N],du[N]; int n,m; bool topo() { queue<int> q; for(int i=1; i<=n; i++) if(du[i]==0) q.push(i); int cnt=0; while(!q.empty()) { int t=q.front(); for(int i:g[t]) { du[i]--; if(du[i]==0) q.push(i); } cnt++; q.pop(); } if(cnt!=n) return false; return true; } int main() { std::ios::sync_with_stdio(false); cin>>n>>m; for(int i=1; i<=m; i++) { int u,v; cin>>u>>v; g[u].push_back(v); col[i]=(u<v); du[v]++; } if(topo()) { cout<<1<<endl; for(int i=1;i<=m;i++) cout<<1<<" "; cout<<endl; } else { cout<<2<<endl; for(int i=1;i<=m;i++) cout<<col[i]+1<<" "; cout<<endl; } return 0; }