題意:
有n個點m條邊組成的有向圖,要給邊塗色,使得不存在一個由相同顏色組成的環。
思路:
如果圖中本來就沒有環,全部塗成一種顏色即可。
有環的情況時,由於一個組成一個環的邊必定有兩種邊,編號小的–>編號大的、編號大的–>編號小的。把這兩種邊塗成兩種顏色即可。
參考代碼:
#include <bits/stdc++.h>
using namespace std;
const int N=5e3+5;
int head[N],cnt;
struct node{
int u,v,id,nxt;
}edge[N<<1];
void add_edge(int u,int v,int id){
edge[++cnt].u=u;
edge[cnt].v=v;
edge[cnt].nxt=head[u];
edge[cnt].id=id;
head[u]=cnt;
}
int ind[N];
queue<int>q;
int ans[N];
bool vis[N];
int sz;
void topu(){
while (!q.empty()){
int u=q.front();
q.pop();
sz++;
vis[u]= true;
for(int i=head[u];~i;i=edge[i].nxt){
int v=edge[i].v;
ans[edge[i].id]=1;
ind[v]--;
if(!ind[v]){
q.push(v);
}
}
}
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
memset(head,-1, sizeof(head));
for(int i=1,u,v;i<=m;i++){
scanf("%d%d",&u,&v);
ind[v]++;
add_edge(u,v,i);
}
for(int i=1;i<=n;i++){
if(!ind[i]){
q.push(i);
}
}
sz=0;
topu();
printf("%d\n",sz==n?1:2);
for(int i=1;i<=m;i++){
if(sz==n)ans[edge[i].id]=1;
else ans[edge[i].id]=edge[i].u<edge[i].v?1:2;
}
for(int i=1;i<=m;i++){
printf("%d%c",ans[i],i==m?'\n':' ');
}
return 0;
}