【t075】郁闷的记者

Time Limit: 1 second
Memory Limit: 128 MB

【问题描述】

你是一个体育报社的记者,你接受到一个艰难的任务:有N支足球队参加足球比赛,现在给你一些比赛的结果,需要你给出各支球
队的排名,从1到N。
以下是给你的一些信息:
(1) 没有平局;
(2) 不同的球队排名不能相同;
(3) 对于所有满足(1<=a),(a小于b),(b<=n),第a名的球队一定可以打败第b名的球队。
给你部分比赛结果,要求给出排名,并且判断是否存在另一种排名方法满足给你的比赛结果。
【数据范围】
30%的数据 (1<=N<=7,1<=M<=15)
60%的数据(1<=N<=100,1<=M<=2000)
【输入格式】

第一行输入N(1<=N<=5000),表示球队的数量,编号为1到N。第二行输入M(1<=M<=100,000),表示给出的比赛场数,接下来M行,每
行两个整数X_i,Y_i,表示X_i能打败Y_i。

【输出格式】

输出包含N+1行,前N行描述球队的排名,第i个数表示第i名的球队,第N+1行包含一个整数,如果为0表示不存在其他的排名方法,否则为1表示还有其他的排名方法。

Sample Input

4
5
1 2
3 1
3 2
3 4
4 1

Sample Output

3
4
1
2
0

Sample Input1

3
2
2 1
2 3

Sample Output1

2
1
3
1

【题目链接】:http://noi.qz5z.com/viewtask.asp?ID=t075

【题解】

拓扑排序;
对于给的关系(x,y)
建一条从x指向y的单向边;
y的入度递增;
然后做拓扑排序;
每次找入度为0的点;
(直接输出)
然后修改它的邻点的入度;(递减1)
如果有一次找到的入度为0的点大于1;
就说明有多个拓扑序;
说明有多个排名;
否则没有;
(平台没有特判,每次输出的时候找标号最小的输出,[斜眼笑])

【完整代码】

#include <cstdio>
#include <vector>
using namespace std;
#define rei(x) scanf("%d",&x)
#define rep1(i,x,y) for (int i = x;i <= y;i++)

const int MAXN = 5e3+100;

int n,m,du[MAXN],yes = 0;
vector <int> g[MAXN];

int main()
{
    //freopen("F:\\rush.txt","r",stdin);
    rei(n);
    rei(m);
    rep1(i,1,m)
    {
        int x,y;
        rei(x);rei(y);
        du[y]++;
        g[x].push_back(y);
    }
    while (true)
    {
        int cnt = 0,j=-1;
        rep1(i,1,n)
            if (du[i]==0)
            {
                cnt++;
                if (cnt==1) j = i;
            }
        if (cnt>1) yes = 1;
        if (j==-1)
            break;
        du[j] = -1;
        int len = g[j].size();
        rep1(i,0,len-1)
            du[g[j][i]]--;
        printf("%d\n",j);
    }
    printf("%d\n",yes);
    return 0;
}
posted @ 2017-10-04 18:45  AWCXV  阅读(251)  评论(0编辑  收藏  举报