题意:有很多机器人,其中如果1号打败2号,2号打败3号,那么1号也可以打败3号,给你m场比赛的结果,问最少需要知道前几场就可以确定机器人的排名
思路:二分答案,然后拓扑排序看看是否成一条直线即可
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 100001
#define LL long long
int cas=1,T;
int n;
vector<int>G[maxn];
int in[maxn];
int e[maxn],e1[maxn];
bool topo(int m)
{
memset(in,0,sizeof(in));
for (int i = 0;i<=n;i++)
G[i].clear();
for (int i = 1;i<=m;i++)
{
G[e[i]].push_back(e1[i]);
in[e1[i]]++;
}
queue<int>q;
int sum = 0;
for (int i = 1;i<=n;i++)
if (in[i]==0)
q.push(i);
while (!q.empty())
{
int u = q.front();q.pop();
if (q.size())
return false;
sum++;
for (int i = 0;i<G[u].size();i++)
{
int v = G[u][i];
if (--in[v]==0)
q.push(v);
}
}
return true;
//return sum==n;
}
int main()
{
int k;
while (scanf("%d%d",&n,&k)!=EOF)
{
for (int i = 1;i<=k;i++)
scanf("%d%d",&e[i],&e1[i]);
int l=1,r=k;
int ans = -1;
while (l<=r)
{
int m = (l+r)/2;
if (topo(m))
r=m-1,ans=m;
else
l=m+1;
}
printf("%d\n",ans);
}
//freopen("in","r",stdin);
//scanf("%d",&T);
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}