Loading

Coloring Edges

\(Solution\)

link

一个经典结论是有向图中的任意一个环总能由一条生成树上的从祖先到儿子的链以及一条返祖边组成,正确性显然。

不妨将所有树边和横插边都染成黑色,返祖边染成白色,这样就可以保证任意一个环都有两种颜色了。

判断横插边和返祖边可以用栈来维护。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 5e3 + 5;

int n, m;
vector<PII> e[N];
int ans[N];
bool st[N], ins[N];

void dfs(int u) {
	st[u] = true;
	ins[u] = true;
	for (auto [v, id] : e[u]) {
		if (!st[v]) {
			ans[id] = 1;
			dfs(v);
		}
		else {
			if (ins[v]) ans[id] = 2;
			else ans[id] = 1;
		}
	}
	ins[u] = false;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr); cout.tie(nullptr);

    cin >> n >> m;
    for (int i = 1; i <= m; i ++) {
    	int u, v;
    	cin >> u >> v;
    	e[u].emplace_back(v, i);
    }
    for (int i = 1; i <= n; i ++) {
    	if (!st[i]) {
    		dfs(i);
    	}
    }
    cout << *max_element(ans + 1, ans + 1 + m) << '\n';
    for (int i = 1; i <= m; i ++) {
    	cout << ans[i] << ' ';
    }
    return 0;
}
posted @ 2024-02-29 19:51  Svemit  阅读(24)  评论(0)    收藏  举报