• NWPU省赛热身赛——D,入度和出度


    题目的意思是给一张有向图,如果有环,那么输出“ You will fail some exam ,but I think I can deal with it. ”否则,如果有多条路径可以遍历完所有的点,那么输出“It's too easy.I've found many solutions in my first glance.”否则输出“I've got it by using my IQ and RP.”并且在下一行输出唯一的路径。

    这道题提议比较明确,就是用每个点的入度来写,如果没有点的入度为0,那么就是代表有环,输出上面说的第一种状态,如果有多个点入读为0,那么就是第二种状态???(第一次是这样考虑的,wa了一发,真是蠢)。对于这道题,我们应该先遍历一遍有没有环环,即每次去掉所有入度为0的点,并且把所有与这些点相连的点的入度减去1,如果遇到环就返回。遍历玩无环后,再进行一次遍历,看看每次入度为0的点有多少个,如果个数>1那么,就是状态2,不然就记录下这个点,知道遍历完所有点,记录下的点的顺序即是要输出的路径。

    遍历的过程可以用队列来维护。

    下面是AC代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <queue>
    
    using namespace std;
    
    const int MAXN = 1555;
    int n,k,in[MAXN],inq[MAXN],ou[MAXN],ou_cnt,tem[MAXN],tem_cnt;
    vector <int> G[MAXN];
    bool vis[MAXN];
    
    void bfs(int u){
        queue <int> q;
        q.push(u);
        vis[u] = true;
        while(!q.empty()){
            int x = q.front();  q.pop();
            vis[x] = true;
            for(int i = 0;i < G[x].size();i ++){
                int v = G[x][i];
                in[v]--;
                if(!in[v])
                    q.push(v);
            }
        }
    }
    
    bool solve(int u){
        queue <int> q;
        q.push(u);
        while(!q.empty()){
            int x = q.front();  q.pop();
            int cnt = 0;
            for(int i = 0;i < G[x].size();i ++){
                int v = G[x][i];
                inq[v]--;
                if(!inq[v]){
                    ou[ou_cnt++] = v;
                    cnt++;
                    q.push(v);
                }
            }
            if(cnt > 1)
                return false;
        }
        return true;
    }
    
    int main()
    {
        //freopen("test.in","r",stdin);
        while(~scanf("%d%d",&n,&k)){
            memset(in,0,sizeof(in));
            memset(vis,0,sizeof(vis));
            for(int i = 0;i < n+1;i ++) G[i].clear();
            for(int i = 0;i < k;i ++){
                int u,v;
                scanf("%d",&u);
                while(scanf("%d",&v) && v!=0){
                    G[v].push_back(u);
                    in[u]++;
                }
            }
            tem_cnt = 0;
            in[0] = 0;
            for(int i = 1;i <= n;i ++){
                if(!in[i]){
                    in[i]++;
                    G[0].push_back(i);
                }
            }
            for(int i = 0;i <= n;i ++)  inq[i] = in[i];
            bfs(0);
            bool flag = true;
            for(int i = 1;i <= n;i ++){
                if(in[i]){
                    flag = false;
                    break;
                }
            }
            if(!flag)   printf("You will fail some exam ,but I think I can deal with it.
    ");
            else {
                ou_cnt = 0;
                if(!solve(0))  printf("It's too easy.I've found many solutions in my first glance.
    ");
                else{
                    printf("I've got it by using my IQ and RP.
    ");
                    for(int i = 0;i < ou_cnt-1;i ++){
                        printf("%d ",ou[i]);
                    }
                    printf("%d
    ",ou[ou_cnt-1]);
                }
            }
        }
        return 0;
    }


  • 相关阅读:
    PPT能输英文不能输汉字
    常用HTML正则表达式
    Log4j使用总结
    JsonConfig过滤对象属性
    打开”我的电脑“,不显示”共享文档“和”我的文档“,解决办法。(windows XP系统)
    错误org.hibernate.LazyInitializationException
    Tomcat中实现IP访问限制
    windows server 2008中让AD域中的普通用户可以 远程登录 域控服务器。
    ibatis简介及 like查询
    IE访问页面的时候,受限制的解决方案。
  • 原文地址:https://www.cnblogs.com/hqwhqwhq/p/4555874.html
Copyright © 2020-2023  润新知