Educational Codeforces Round 72 D. Coloring Edges(拓扑判环)
题意:现在有n个点,m条有向边,现在要对这m条有向边染色,染色的要求是在一个环里面的边的颜色不能相同,
现在让你求出最少要几种颜色,才能满足条件的染色,并输出方案数
首先判断有无环,没环直接1,
有环的话,设计一种染色方案(差不多是个构造?CF里面好多方案不唯一的都要自己指定一种行之有效的方案出来)
考虑存在环的时候,必然既存在从小点指向大点的边,也存在从大点指向小点的边,对这两种边分别染色就可以保证环内颜色不同,
所以最多只需要两种颜色
#include <bits/stdc++.h> using namespace std; #define endll '\n' #define C getchar() typedef long long ll; #define pi acos(-1.0) #define INF 0x3f3f3f3f #define mod 1000000007 #define pii pair<int, int> const int MAXN = 2e5 + 10; #define stop system("pause") #define lowbit(x) ((x) & (-x)) #define Temp template <typename T> #define mem(a, b) memset(a, b, sizeof(a)) #define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) Temp inline void rd(T &s) { s = 0;T t = 1, k = C; for (; k < '0' || k > '9'; k = C)if (k == '-') t = -1; for (; k >= '0' && k <= '9'; k = C) s = (s << 1) + (s << 3) + (k ^ 48); s *= t; } // int n,m; int in[MAXN]; vector<int>mp[MAXN]; int topo() { queue<int>q; for(int i=1;i<=n;i++) //n 节点的总数 if(in[i]==0) q.push(i); //将入度为0的点入队列 int k=0; while(!q.empty()) { int p=q.front(); q.pop(); // 选一个入度为0的点,出队列 k++; for(int i=0;i<mp[p].size();i++) { int y=mp[p][i]; if((--in[y])==0) q.push(y); } } if(k==n) return 1;//无环 else return 0;// ans 中的长度与n不相等,就说明无拓扑序列,有环 } char ans[MAXN]; int main() { rd(n),rd(m); for(int i=0;i<m;++i) { int u,v;rd(u),rd(v); mp[u].push_back(v); in[v]++; if(u<v) ans[i]='1'; else ans[i]='2'; } if(topo()) { printf("1\n"); for(int i=0;i<m;++i) printf("1 "); cout<<endll; } else { printf("2\n"); for(int i=0;i<m;++i) printf("%c ",ans[i]); cout<<endll; } //stop; return 0; }