首页 > 代码库 > 【CF711D】Directed Roads(想法题,环,强连通分量)

【CF711D】Directed Roads(想法题,环,强连通分量)

题意:

  给一张N个点N条有向边的图,边可以逆向。问任意逆向若干条边使得这张图无环的方案数(mod 1e9+7)。

n<=200000

思路:三个样例给的好 找规律方便很多

        易得有N点的环有(2^n)-2中改法,除了不改和都改

        剩下的都是链,设除环外还有K个点,他们的总贡献就是2^k,因为都是一条边相连接怎么改也没有环

        CF上快速幂要写在外面不然会出现奇奇怪怪的CE

 1 const mo=1000000007; 2 var head,vet,next,stack,low,dfn,b,s,flag:array[1..500000]of longint; 3     n,tot,i,id,time,top,x,m:longint; 4     ans,f,tmp:int64; 5  6 procedure add(a,b:longint); 7 begin 8  inc(tot); 9  next[tot]:=head[a];10  vet[tot]:=b;11  head[a]:=tot;12 end;13 14 function min(x,y:longint):longint;15 begin16  if x<y then exit(x);17  exit(y);18 end;19 20 procedure dfs(u:longint);21 var e,v:longint;22 begin23  flag[u]:=1;24  inc(top); stack[top]:=u;25  inc(time); dfn[u]:=time; low[u]:=time;26  e:=head[u];27  while e<>0 do28  begin29   v:=vet[e];30   if flag[v]=0 then31   begin32    dfs(v);33    low[u]:=min(low[u],low[v]);34   end35    else if s[v]=0 then low[u]:=min(low[u],low[v]);36   e:=next[e];37  end;38  if dfn[u]=low[u] then39  begin40   inc(id); s[u]:=id; inc(b[id]);41   while (top>0)and(stack[top]<>u) do42   begin43    s[stack[top]]:=id;44    inc(b[id]);45    stack[top]:=0;46    dec(top);47   end;48   stack[top]:=0; dec(top);49  end;50 end;51 52 begin53 54  readln(n);55  for i:=1 to n do56  begin57   read(x);58   add(i,x);59  end;60  for i:=1 to n do61   if flag[i]=0 then dfs(i);62  m:=0;63  for i:=1 to n do64   if b[s[i]]=1 then m:=m+1;65  ans:=1;66  for i:=1 to id do67   if b[i]>1 then68   begin69    f:=1; tmp:=2;70    while b[i]>0 do71    begin72     if b[i] mod 2=1 then f:=f*tmp mod mo;73     tmp:=tmp*tmp mod mo;74     b[i]:=b[i] div 2;75    end;76    ans:=(ans*(f-2)) mod mo;77   end;78   ans:=(ans+mo) mod mo;79   f:=1; tmp:=2;80   while m>0 do81   begin82    if m mod 2=1 then f:=f*tmp mod mo;83    tmp:=tmp*tmp mod mo;84    m:=m div 2;85   end;86   ans:=ans*f mod mo;87  writeln(ans);88 89 end.

 

【CF711D】Directed Roads(想法题,环,强连通分量)