• CodeForces-1217D (拓扑排序/dfs 判环)


    题意

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

    请给一个有向图着色,使得没有一个环只有一个颜色,您需要最小化使用颜色的数量。

    思路

    因为是有向图,每个环两个颜色就可以满足了。所以最大为2,最小为1。

    法1 dfs:

    用dfs判断有向图的环,每次把构成环的最后那条边染成2,其余染成1。

    法2 拓扑排序:

    容易发现,对于一个有向图,如果成环那么点的序号必不是单调的,因为最后的那个点又会连回起始点。

    所以我们把u<v染成1,u>v染成2,然后拓扑排序判环,如果有环那么就输出染色方案,否则全输出1。

    代码

    法1:

    #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:

    #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;
    }
    

      

  • 相关阅读:
    网络攻击与防御 实验1
    java继承 、方法重写、重写toString方法
    递归算法
    加标签的continue用法
    程序员,你应该知道的数据结构之栈
    SpringBoot 内部方法调用,事务不起作用的原因及解决办法
    程序员,你应该知道的数据结构之哈希表
    程序员,你应该知道的数据结构之跳表
    程序员,你应该知道的二分查找算法
    程序员,你应该知道的基础排序算法
  • 原文地址:https://www.cnblogs.com/mcq1999/p/11983585.html
Copyright © 2020-2023  润新知