一个有向图,把边染色后使得相同颜色的边无法构成环,求最大颜色数。
原图若没有环,则答案为1,否则答案为2,只要一个环中的边染不同颜色即可。问题就是如何高效的使环中的边染不同颜色,考虑到是有向图,如果有环,则肯定有a - > b , b -> c , c -> a 类似的情形,因此只要判断边的两个端点大小即可,
u > v 染1
u < v 染2
这样环中必定有不同的颜色
/*************************************************************************
> File Name: 1217D.cpp
> Author: windhxs
> Mail: 865022197@163.com
> Created Time: 2019年09月09日 星期一 12时05分11秒
************************************************************************/
#include<bits/stdc++.h>
using namespace std;
#define f first
#define s second
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
const int N = 5e3 + 10;
const int M = 5e3 + 10;
int n,m,a,b;
int h[N],nt[M],to[M],cnt,color[M],deg[N];
void add(int a,int b){
to[++cnt] = b;
nt[cnt] = h[a];
h[a] = cnt;
deg[b]++;
}
int topo(){
queue<int> Q;
int cnt = 0;
for(int i = 1; i <= n ; i++){
if(!deg[i]) Q.push(i),cnt++;
}
while(!Q.empty()){
int u = Q.front();
Q.pop();
for(int i = h[u] ; i; i = nt[i]){
int t = to[i];
if(--deg[t] == 0) cnt++,Q.push(t);
}
}
if(cnt == n) return 1;
else return 0;
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
cin>>n>>m;
for(int i = 0 ; i < m ; i++) {
cin>>a>>b;
add(a,b);
if(a > b) color[i] = 1;
else color[i] = 2;
}
if(topo()){
cout<<1<<endl;
for(int i = 0 ; i < m ;i ++) cout<<"1 ";
cout<<endl;
}
else {
cout<<2<<endl;
for(int i= 0 ; i < m; i ++) cout<<color[i]<<' ';
cout<<endl;
}
return 0;
}