CF #CROC 2016 - Elimination Round D. Robot Rapping Results Report 二分+拓扑排序

时间:2023-03-08 23:58:59
CF #CROC 2016 - Elimination Round D. Robot Rapping Results Report 二分+拓扑排序

题目链接:http://codeforces.com/contest/655/problem/D

大意是给若干对偏序,问最少需要前多少对关系,可以确定所有的大小关系。

解法是二分答案,利用拓扑排序看是否所有关系被唯一确定。即任意一次只能有1个元素入度为0入队。

 #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <queue>
#include <stack>
#include <map>
#include <set> using namespace std; const int N=; struct Edge {
int to,next;
Edge() {}
Edge(int _to,int _nxt):to(_to),next(_nxt) {}
} edge[N<<];
int idx=,head[N];
void addedge(int u,int v) {
edge[++idx]=Edge(v,head[u]);
head[u]=idx;
}
int in[N],que[N]; int a[N],b[N]; bool topoSort(int n,int mid){
idx=;memset(head,,sizeof head);
memset(in,,sizeof in);
for (int i=;i<=mid;i++) {
addedge(a[i],b[i]);
in[b[i]]++;
}
int tail=;
for (int i=;i<=n;i++)
if (in[i]==)
que[tail++]=i;
if (tail>) return false;
for (int i=;i<tail;i++){
int cnt=;
for (int k=head[que[i]];k;k=edge[k].next){
int v=edge[k].to;
in[v]--;
if (in[v]==){
cnt++;
if (cnt>) return false;
que[tail++]=v;
}
}
}
return true;
} int main() {
int n,m;
scanf("%d %d",&n,&m);
for (int i=;i<=m;i++) {
scanf("%d %d",a+i,b+i);
}
int low=,high=m,ret=-;
while (low<=high) {
int mid=(low+high)>>;
if (topoSort(n,mid)) {
ret=mid;
high=mid-;
}
else
low=mid+;
}
printf("%d\n",ret);
return ;
}