CF1217D Coloring Edges 判断有无环的有向图
Posted ch-hui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1217D Coloring Edges 判断有无环的有向图相关的知识,希望对你有一定的参考价值。
题意:给你一张有向图,n个点,m条边,要求同一个环里的边不可以全部都为同一种颜色。问最少要涂多少种颜色,并依次给每条边编颜色号。
思路:简单的拓扑想法,一开始我用BFS的拓扑发现一直RE3,然后我就改了个很简单的DFS拓扑的样子,用邻接表vector连接每一个点。
在我用DFS的时候发现了一个问题,比如1->2,1->3,2->3,如果访问过的都编为vis[i]=1,则误把他弄成一个环了,所以访问完之后把vis[i]的值变为2就OK了,比如刚刚那个,先访问1->2,2->3,访问结束vis[3]=2先,然后回到1那里判断1->3,vis[3]刚好之前变了2,就不会判断一个错误的环了。(其实也不算拓扑吧=。=)
呈上代码!
#include <iostream> #include <vector> #include<cmath> #include <set> #include <map> #include <queue> #include <stack> #include <algorithm> using namespace std; #define ll long long #define N 200005 int degree[N],u[N],v[N]; vector<int>G[N]; int n, m; int flag = 0; int vis[N]; void topo(int u) { if (flag)return; vis[u] = 1;//已被访问过一次 for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (!vis[v])topo(v);//访问下一个点 else if (vis[v] == 1) { flag = 1;//有环出现 return; } } vis[u] = 2;//结束访问 } int main() { ll i, j, k; cin >> n >> m; for (i = 1; i <= m; i++) { cin >> u[i] >> v[i]; G[u[i]].push_back(v[i]);//邻接表 } for (i = 1; i <= n; i++) if (!vis[i]) topo(i); if (flag) { cout << 2 << endl; for (i = 1; i <= m; i++) if (u[i] < v[i]) cout << 1 << " "; else cout << 2 << " "; cout << endl; } else { cout << 1 << endl; for (i = 1; i <= m; i++) cout << 1 << " "; cout << endl; } return 0; }
以上是关于CF1217D Coloring Edges 判断有无环的有向图的主要内容,如果未能解决你的问题,请参考以下文章
Educational Codeforces Round 72 (Rated for Div. 2)-D. Coloring Edges-拓扑排序
CF1354E Graph Coloring (二分图+dp)
CF576E Painting Edges [线段树分治,可撤销并查集]