https://vjudge.net/contest/382704#problem/A
题目大意:给一张有向图涂色,要求同一个环里的边不可以全都是同一种颜色。问最少需要多少种颜色,并按顺序输出各边的涂色。
解题思路:
- 画图可得颜色种类数只能是1或2。当不存在环时,全部涂1。当存在环时,可按照to和from的大小关系来分别涂1和2.
- 有向图用拓扑来判断是否有环,当入度为0时,节点入队;而环上的节点的入度始终不可能为0,故不能入队
参考博客:link
#include<bits/stdc++.h>
#define ll long long
#define MAXN 100010
using namespace std;
int n,m;
struct edge{
int from,to;
}e[5010];
int in[5010];
vector<int> X[5010];
int cnt;
void addedge(int a,int b){
e[cnt].from=a;
e[cnt++].to=b;
}
queue<int> q;
bool judge(){//
int ans=0;
for(int i=1;i<=n;i++){
if(!in[i]) q.push(i),ans++;
}
while(!q.empty()){
int temp=q.front();q.pop();
for(int i=0;i<X[temp].size();i++){
int x=X[temp][i];
in[x]--;
if(!in[x]) q.push(x),ans++;
}
}
if(ans<n) return true;
else return false;
}
void init(){
for(int i=1;i<=n;i++){
X[i].clear();
}
}
int main(){
scanf("%d%d",&n,&m);
init();
int a,b;
for(int i=0;i<m;i++){
scanf("%d%d",&a,&b);
addedge(a,b);
in[b]++;
X[a].push_back(b);
}
if(judge()){
printf("2\n");
for(int i=0;i<m;i++){
if(e[i].from>e[i].to)printf("2 ");
else printf("1 ");
}
return 0;
}
printf("1\n");
for(int i=1;i<=m;i++){
printf("1 ");
}
}