CodeForces-1217D (拓撲排序/dfs 判環)

題意

https://vjudge.net/problem/CodeForces-1217Dios

請給一個有向圖着色,使得沒有一個環只有一個顏色,您須要最小化使用顏色的數量。c++

思路

由於是有向圖,每一個環兩個顏色就能夠知足了。因此最大爲2,最小爲1。spa

法1 dfs:.net

用dfs判斷有向圖的環,每次把構成環的最後那條邊染成2,其他染成1。blog

法2 拓撲排序:排序

容易發現,對於一個有向圖,若是成環那麼點的序號必不是單調的,由於最後的那個點又會連回起始點。ci

因此咱們把u<v染成1,u>v染成2,而後拓撲排序判環,若是有環那麼就輸出染色方案,不然全輸出1。get

代碼

法1:it

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int N=5e3+5;
const int mod=1e9+7;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
vector<int> g[N];
int e[N][N],vis[N],col[N],gg,in[N];
void dfs(int u)
{
    int sz=g[u].size();
    in[u]=1;
    for(int i=0;i<sz;i++)
    {
        int v=g[u][i];
        if(!vis[v])
        {
            vis[v]=1;
            col[e[u][v]]=1;
            dfs(v);
        }
        else if(in[v])
        {
            col[e[u][v]]=2;
            gg=1;
        }
        else
        {
            col[e[u][v]]=1;
        }
    }
    in[u]=0;
}
int main()
{
    std::ios::sync_with_stdio(false);
    int n,m;
    while(cin>>n>>m)
    {
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=m;i++)
        {
            int u,v;
            cin>>u>>v;
            g[u].push_back(v);
            e[u][v]=i;
        }
        gg=0;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
             //   col[i]=1;
                vis[i]=1;
                dfs(i);
            }
        }
        if(!gg)
        {
            cout<<1<<endl;
            for(int i=1;i<=m;i++)
                cout<<1<<" ";
            cout<<endl;
        }
        else
        {
            cout<<2<<endl;
            for(int i=1;i<=m;i++)
                cout<<col[i]<<" ";
            cout<<endl;
        }
    }
    return 0;
}

  

法2:io

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int N=200005;
const int mod=1e9+7;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
vector<int> g[N];
int col[N],du[N];
int n,m;
bool topo()
{
    queue<int> q;
    for(int i=1; i<=n; i++)
        if(du[i]==0) q.push(i);
    int cnt=0;
    while(!q.empty())
    {
        int t=q.front();
        for(int i:g[t])
        {
            du[i]--;
            if(du[i]==0)
                q.push(i);
        }
        cnt++;
        q.pop();
    }
    if(cnt!=n)
        return false;
    return true;
}
int main()
{
    std::ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1; i<=m; i++)
    {
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        col[i]=(u<v);
        du[v]++;
    }
    if(topo())
    {
        cout<<1<<endl;
        for(int i=1;i<=m;i++)
            cout<<1<<" ";
        cout<<endl;
    }
    else
    {
        cout<<2<<endl;
        for(int i=1;i<=m;i++)
            cout<<col[i]+1<<" ";
        cout<<endl;
    }
    return 0;
}
相關文章
相關標籤/搜索