• 「日常训练」Jin Yong’s Wukong Ranking List(HihoCoder-1870)


    题意与分析

    2018ICPC北京站A题。
    题意是这样的,给定若干人的武力值大小(A B的意思是A比B厉害),问到第几行会出现矛盾。
    这题不能出现思维定势,看到矛盾就是矛盾并查集——A>B、A>C是不能推出B>C或者B<C的。相反,大于小于是一种偏序关系,是可以建立有向图的。那么,如果这个有向图中出现了环,就是矛盾的。
    问题于是转化为有向图判环问题,这里简单说一下有向图和无向图的判环方法。

    a) 无向图

    1. 删除所有度<=1的顶点及相关的边,并将另外与这些边相关的其它顶点的度减一。
    2. 将度数变为1的顶点排入队列,并从该队列中取出一个顶点重复步骤一。

    最后如果最后还有未删除顶点,则存在环,否则没有环。

    b) 有向图
    对于n个节点的有向图,令cnt = 0。

    1. 将所有入度为0的节点入队;
    2. 将队头节点v出队,cnt++,直至队列为空;
    3. 遍历与v相连的节点,并将相连节点的入度减一,若入度变为0,将此节点入队。

    最后,若cnt==n,访问到所有节点,完成拓扑排序(这是出队顺序的意义),否则,存在环。

    代码

    /* ACM Code written by Sam X or his teammates.
     * Filename: a.cpp
     * Date: 2018-11-17
     */
    
    #include <bits/stdc++.h>
    
    #define INF 0x3f3f3f3f
    #define PB emplace_back
    #define MP make_pair
    #define fi first
    #define se second
    #define rep(i,a,b) for(repType i=(a); i<=(b); ++i)
    #define per(i,a,b) for(repType i=(a); i>=(b); --i)
    #define ZERO(x) memset(x, 0, sizeof(x))
    #define MS(x,y) memset(x, y, sizeof(x))
    #define ALL(x) (x).begin(), (x).end()
    
    #define QUICKIO                  
        ios::sync_with_stdio(false); 
        cin.tie(0);                  
        cout.tie(0);
    #define DEBUG(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
    
    using namespace std;
    using pi=pair<int,int>;
    using repType=int;
    using ll=long long;
    using ld=long double;
    using ull=unsigned long long;
    
    const int MAXN=25;
    vector<int> G[MAXN];
    vector<pi> edges;
    void add_edge(int u,int v)
    {
        edges.PB(u,v);
        G[u].PB(edges.size()-1);
    }
    int vis[MAXN];
    int n;
    unordered_map<string,int> ma;
    vector<string> idx;
    int gh(string str)
    {
        if(ma.find(str)==ma.end())
        {
            idx.PB(str);
            return ma[str]=idx.size()-1;
        }
        return ma[str];
    }
    
    bool has_loop()
    {
        int cnt=0;
        queue<int> q;
        int deg[MAXN];
        ZERO(deg);
        rep(i,0,int(edges.size())-1)
        {
            deg[edges[i].se]++;
        }
        rep(i,0,idx.size()-1)
            if(deg[i]==0)
            {
                q.push(i);
            }
        while(!q.empty())
        {
            //cout<<"Now: "<<q.front()<<endl;
            cnt++;
            auto now=q.front(); q.pop();
            rep(i,0,int(G[now].size())-1)
            {
                deg[edges[G[now][i]].se]--;
                if(deg[edges[G[now][i]].se]==0)
                    q.push(edges[G[now][i]].se);
            }
        }
        //cout<<cnt<<" and "<<idx.size()<<endl;
        return cnt!=idx.size();
    }
    int
    main()
    {
        while(cin>>n)
        {
            bool ok=true;
            idx.clear();
            ma.clear();
            rep(i,0,20) G[i].clear();
            edges.clear();
            rep(i,1,n)
            {
                string stra,strb;
                cin>>stra>>strb;
                if(!ok) continue;
                int u=gh(stra), v=gh(strb);
                //cout<<"Add: "<<u<<" "<<v<<endl;
                add_edge(u,v);
                if(has_loop())
                {
                    cout<<stra<<" "<<strb<<endl;
                    ok=false;
                }
            }
            if(ok) cout<<0<<endl;
        }
    
        return 0;
    }
    
  • 相关阅读:
    同步请求和异步请求的区别
    Ajax初步理解
    ajax的GET和POST请求
    What's this?(js)
    rxjs
    Angular7_获取异步方法里面的数据
    Angular7_人员登记系统
    Angular7
    特殊操作符
    Oracle 表操作
  • 原文地址:https://www.cnblogs.com/samhx/p/Hihocoder-1870.html
Copyright © 2020-2023  润新知