【CF645D】 Robot Rapping Results Report(拓扑排序,二分)

题意:有一张N点M边的有向图,求最小的K使根据前K条边就能够确定图是否有唯一的拓扑序,

        若没有唯一拓扑序输出-1

思路:二分答案再拓扑排序,以入度为0的节点作为新的一层,若某一层的节点个数<>1则没有唯一拓扑序

 1 var head,vet,next,d,x,y,b:array[1..210000]of longint;
 2     n,m,i,l,r,mid,last,tot:longint;
 3 
 4 procedure add(a,b:longint);
 5 begin
 6  inc(tot);
 7  next[tot]:=head[a];
 8  vet[tot]:=b;
 9  head[a]:=tot;
10 end;
11 
12 function isok(len:longint):boolean;
13 var s,e,i,st,v:longint;
14 begin
15  fillchar(head,sizeof(head),0);
16  fillchar(b,sizeof(b),0);
17  fillchar(d,sizeof(d),0);
18  tot:=0;
19  for i:=1 to len do
20  begin
21   add(x[i],y[i]);
22   inc(d[y[i]]);
23  end;
24  s:=0;
25  for i:=1 to n do
26   if d[i]=0 then begin st:=i; b[i]:=1; inc(s); end;
27  if s<>1 then exit(false);
28  for i:=1 to n-1 do
29  begin
30   e:=head[st];
31   while e<>0 do
32   begin
33    v:=vet[e];
34    dec(d[v]);
35    e:=next[e];
36   end;
37   e:=head[st]; s:=0;
38   while e<>0 do
39   begin
40    v:=vet[e];
41    if (d[v]=0)and(b[v]=0) then
42    begin
43     inc(s); b[v]:=1; st:=v;
44    end;
45    e:=next[e];
46   end;
47   if s<>1 then exit(false);
48  end;
49  exit(true);
50 end;
51 
52 begin
53 // assign(input,'cf645D.in'); reset(input);
54 // assign(output,'cf645D.out'); rewrite(output);
55  readln(n,m);
56  for i:=1 to m do readln(x[i],y[i]);
57  l:=1; r:=m; last:=m+1;
58  while l<=r do
59  begin
60   mid:=(l+r)>>1;
61   if isok(mid) then begin last:=mid; r:=mid-1; end
62    else l:=mid+1;
63  end;
64  if last=m+1 then writeln(-1)
65   else writeln(last);
66  //close(input);
67 // close(output);
68 end.

 

posted on 2016-11-05 14:50  myx12345  阅读(239)  评论(0编辑  收藏  举报

导航