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


原文地址:https://www.cnblogs.com/hqwhqwhq/p/4555874.html