- 题意: 无自环和重边的有向图,给边染色使得环上到边不全为同一颜色,求最少的颜色与染色方案
- 思路: 先建立树形图,则构成环的一定是反向边,一条反向边只会构成一个环,将反向边染成2,其他的染成1
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define FOR(i,n) for(int i=1;i<=n;++i)
#define ll long long
#define fi first
#define se second
using namespace std;
typedef pair<int,int> pii;
const int N = 5*1e3+10;
vector<int> G[N];
int low[N],vis[N];
stack<int> s;
pii edges[N];
void dfs(int u){
vis[u] = 1;
for(auto to:G[u]){
if(!vis[to]) dfs(to);
}
s.push(u);
}
int main(){
int n,m,u,v,ans = 1;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i){
scanf("%d%d",&u,&v);
edges[i] = {u,v};
G[u].push_back(v);
}
for(int i=1;i<=n;++i){
if(!vis[i]) dfs(i);
}
v = 0;
while(s.size()){
u = s.top(); s.pop();
low[u] = ++v; // 入栈的反向顺序
}
for(int i=1;i<=m;++i){
u = edges[i].first; v = edges[i].second;
if(low[u]>=low[v]){ // 起点终点比晚入栈,说明是反向边
ans = 2; vis[i] = 2;
}else{
vis[i] = 1;
}
}
printf("%d
",ans);
for(int i=1;i<=m;++i){
printf("%d ",vis[i]);
}puts("");
return 0;
}