• 拓扑排序


    拓扑的实现并不难,无论是dfs还是队列实现代码都相对较短,但应用却并不容易

    HDU - 1285   确定比赛名次  HRBUST - 1631

    拓扑应用①排序

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=505;
    int deg[maxn];
    vector<int>g[maxn];
    queue<int>q;
    int n,m,cnt,ans[maxn];
    void add_edge(int u,int v)
    {
        g[u].push_back(v);
    }
    void topo()
    {
       while(!q.empty()) q.pop();
       for(int i=1;i<=n;i++)
            if(!deg[i])
            {q.push(i);deg[i]--;break;}
        while(!q.empty())
        {
            int u=q.front();q.pop();
            ans[cnt++]=u;
            for(auto v:g[u])
            {
                deg[v]--;
            }
            for(int i=1;i<=n;i++)
                 if(!deg[i])
                {
                    q.push(i);
                    deg[i]--;
                    break;
                }
        }
        for(int i=0;i<cnt;i++)
         {
             cout<<ans[i];
             if(i==cnt-1) cout<<endl;
             else cout<<" ";
         }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        while(cin>>n>>m){
        memset(deg,0,sizeof(deg));
        for(int i=0;i<=n;i++)
            g[i].clear();
        cnt=0;
        for(int i=0;i<m;i++)
        {
            int a,b;
            cin>>a>>b;
            add_edge(a,b);
            deg[b]++;
        }
        topo();
      }
        return 0;
    }

    HDU - 1811  Rank of Tetris

    拓扑应用②三种状态(有环,顺序不定,顺序确定)的判别

    因为题目中有排名相同的情况,这里就要考虑用并查集,将相同的归到一类

    判环的时候用到的是sum来标记判断的

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e4+5;
    const int maxm=2e4+5;
    int deg[maxn];
    int par[maxn];
    bool vis[maxn];
    vector<int>g[maxm];
    queue<int>q;
    int n,m,flag1=0,sum;
    void add_edge(int u,int v)
    {
        g[u].push_back(v);
        deg[v]++;
    }
    int findx(int x)
    {
        if(par[x]!=x) par[x]=findx(par[x]);
        return par[x];
    }
    bool unionn(int x,int y)
    {
        x=findx(x);
        y=findx(y);
        if(x==y) return false;
        else{
            par[y]=x;
            return true;
        }
    }
    /*int dfs(int u)//判环
    {
        vis[u]=-1;
        for(auto v:g[u])
        {
            if(vis[v]==-1) return 0;
            else if(vis[v]==0) dfs(v);
        }
        vis[u]=1;
        return 1;
    }*/
    void topo()
    {
       while(!q.empty()) q.pop();
       for(int i=0;i<n;i++)
            if(!deg[i]&&par[i]==i)
            {q.push(i);}
        while(!q.empty())
        {
            if(q.size()>1) flag1=1;
            int u=q.front();q.pop();sum--;
            for(auto v:g[u])
            {
                deg[v]--;
                if(!deg[v])
                    q.push(v);
            }
        }
        if(sum>0) cout<<"CONFLICT"<<endl;
        else if(flag1) cout<<"UNCERTAIN"<<endl;
        else cout<<"OK"<<endl;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        while(cin>>n>>m){
        memset(deg,0,sizeof(deg));
        //memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++)
            par[i]=i;
        for(int i=0;i<=n;i++)
            g[i].clear();
        flag1=0;sum=n;
        for(int i=0;i<m;i++)
        {
            int a,b;
            char c;
            cin>>a>>c>>b;
            if(c=='=') {unionn(a,b);}
            int x=findx(a);
            int y=findx(b);
            if(c=='<') swap(a,b);
            add_edge(a,b);
        }
        /*for(int i=0;i<n;i++)
       {
           if(!vis[i])
           {
               if(!dfs(i)) flag2=1;
           }
       }*/
        topo();
      }
        return 0;
    }

     Codefoeces 510C 哎,,,不太会用dfs版的拓扑,还需要练习

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100;
    int ans[30];
    int vis[30];
    int g[30][30],t;
    string s[maxn+5];
    void init()
    {
        memset(vis,0,sizeof(vis));
        memset(g,0,sizeof(g));
        t=26;
    }
    bool dfs(int u)
    {
        vis[u]=-1;
        for(int i=0;i<26;i++)
        if(g[u][i])
        {
            if(vis[i]==-1) return false;
            else if(!vis[i]&&!dfs(i)) return false;
        }
        vis[u]=1;ans[--t]=u;
        return true;
    }
    bool topo()
    {
        t=26;
        for(int i=0;i<26;i++)
            if(!vis[i])
             if(!dfs(i)) return false;
        return true;
    }
    int main()
    {
        int n,flag;
        cin>>n;
        init();
        for(int i=0;i<n;i++)
            cin>>s[i];
        for(int i=1;i<n;i++)
        {
            flag=0;
            int l=s[i-1].length(),ll=s[i].length();
            for(int j=0;j<min(l,ll);j++)
             {
              if(s[i-1][j]!=s[i][j])
               {
                g[s[i-1][j]-'a'][s[i][j]-'a']=1;
                flag=1;
                break;
                }
             }
            if(!flag)
            {
                if(l>ll)
                {
                    cout<<"Impossible"<<endl;
                    return 0;
                }
            }
        }
        if(topo())
            for(int i=0;i<26;i++)
                cout<<(char)(ans[i]+'a');
        else cout<<"Impossible"<<endl;
        return 0;
    }

  • 相关阅读:
    云服务器Ubuntu更改默认python版本
    例题4-1-3-古老的密码、刽子手的游戏,救济金发放
    Github pages和Hexo搭建自己的博客
    Python字典基本操作介绍
    python win32api win32gui win32con PyUserInput实现自动化脚本
    spring--分类索引
    目录-java并发基础知识
    【转】集群单点故障的应对策略
    CnBlogs自定义博客样式
    读书笔记——《redis入门指南(第2版)》第七章 持久化
  • 原文地址:https://www.cnblogs.com/Egoist-/p/8413608.html
Copyright © 2020-2023  润新知