Codeforces 645D Robot Rapping Results Report【拓扑排序+二分】

题目链接:

http://codeforces.com/problemset/problem/645/D

题意:

给定n个机器人的m个能力大小关系,问你至少要前几个大小关系就可以得到所有机器人的能力顺序。

分析:

拓扑+二分。
注意最终的顺序不能缺点,先把度为0的点入队,如果度为0的点的个数大于1,则说明至少有两个点的能力大小不确定,无法继续。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100005;
vector<int>G[maxn];
int in[maxn], out[maxn];
int ef[maxn], et[maxn];
int n, m;
bool judge(int mid)
{
    memset(in, 0 ,sizeof(in));
    for(int i = 1; i <= n; i++)
        G[i].clear();
    for(int i = 0; i < mid; i++){
        G[ef[i]].push_back(et[i]);
        in[et[i]]++;
    }
    queue<int>q;
    for(int i = 1; i <= n; i++){
        if(!in[i]) q.push(i);
    }
    while(!q.empty()){
        int u = q.front();q.pop();
        if(q.size()) return false;
        for(int i = 0; i < G[u].size(); i++){
            int v = G[u][i];
            in[v]--;
            if(!in[v]) q.push(v);
        }
    }
    return true;
}
int main (void)
{
    cin>>n>>m;
    for(int i = 0; i < m; i++){
        scanf("%d%d", &ef[i], &et[i]);
    }
    int l = 0, r = m;
    while(l < r - 1){
        int mid = (l + 1 +r)/2;
        if(judge(mid)) r = mid;
        else l = mid;
    }
    if(r == m && !judge(m)) return cout<<-1<<endl,0;
    else  cout<<r<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758722.html