Atcoder ABC 139E

Atcoder ABC 139E

题意:

n支球队大循环赛,每支队伍一天只能打一场,求最少几天能打完。

解法:

考虑抽象图论模型,既然一天只能打一场,那么就把每一支球队和它需要交手的球队连边。
求出拓扑序,每次从入度为0的点进行拓扑排序,并把答案加1,删去所有出度,重复该操作。
如果形成环的话就无解。

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define LL long long
#define N 1000010
#define M 1010

using namespace std;

struct Edge {
    int from, to; 
}e[N]; 

int n,num,cnt,tot,ans;
int head[N],a[M][M],node[M][M];
int inq[N],t[N],day[N]; 

inline void add_edge(int x,int y) {
    e[++cnt].from = y;
    e[cnt].to = head[x];
    head[x] = cnt;
}
void topsort() {
    for(int i = 1; i <= tot; i++) {
        int u = t[i]; 
        for(int j = head[u]; j; j = e[j].to) {
            int v = e[j].from; 
            day[v] = day[u] + 1; 
            inq[v]--; 
            if(!inq[v])t[++tot] = v; 
        }
    }
    for(int i = 1; i <= num; i++)
        ans = max(ans, day[i]); 
}

int main() {
    scanf("%d",&n); 
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j < n; j++) {
            scanf("%d",&a[i][j]); 
            if(!node[i][j] && !node[j][i])
                node[i][j] = node[j][i] = ++num; 
        }
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 2; j < n; j++) {
            add_edge(node[i][a[i][j-1]], node[i][a[i][j]]); 
            inq[node[i][a[i][j]]]++; 
        }
    }
    for(int i = 1; i <= num; i++) {
        if(!inq[i]) {
            t[++tot] = i; 
            day[i] = 1; 
        }
    }
    topsort(); 
    if(tot != num) puts("-1"); 
    else printf("%d\n", ans); 
    //system("pause");
    return 0; 
}

猜你喜欢

转载自www.cnblogs.com/Repulser/p/11449131.html