codeforces 645D Robot Rapping Results Report

Posted on 2016-10-05 16:24  ziliuziliu  阅读(148)  评论(0编辑  收藏  举报

二分一下答案check即可。(拓扑排序)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define maxv 100500
#define maxe 200500
using namespace std;
int n,m,nume=0,g[maxv],x[maxv],y[maxv],d[maxv],rank[maxv];
int cnt[maxv];
queue <int> q;
struct edge
{
    int v,nxt;
}e[maxe];
void addedge(int u,int v)
{
    e[++nume].v=v;
    e[nume].nxt=g[u];
    g[u]=nume;
}
bool check(int x)
{
    int ret=0;while (!q.empty()) q.pop();
    for (int i=1;i<=n;i++) {d[i]=0;rank[i]=-1;cnt[i]=0;}
    for (int i=1;i<=x;i++) d[y[i]]++;
    for (int i=1;i<=n;i++)
    {
        if (!d[i])
        {
            if (ret) return false;
            q.push(i);ret++;rank[i]=1;cnt[1]++;
        }
    }
    while (!q.empty())
    {
        int head=q.front();q.pop();
        for (int i=g[head];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (i>x) continue;
            if (!--d[v])
            {
                rank[v]=rank[head]+1;cnt[rank[v]]++;
                q.push(v);
            }
        }
    }
    for (int i=1;i<=n;i++)
    {
        if (cnt[i]!=1)
            return false;
    }
    return true;
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&x[i],&y[i]);
        addedge(x[i],y[i]);
    }
    int l=1,r=m,ans=-1;
    while (l<=r)
    {
        int mid=l+r>>1;
        if (check(mid)) {ans=mid;r=mid-1;}
        else l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}