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;
}
posted @ 2020-04-06 14:28  ch_hui  阅读(143)  评论(0编辑  收藏  举报