Main topic:
In mathematics, we often need to complete a number of propositions equivalence proof. For example, there are 4 propositions a,b,c,d, we prove a↔b, then B↔c, and finally c↔d. Note that each proof is bidirectional, so a total of 6 derivations are completed. Another method is a→b, then b→c, then C→d, and finally D→a, just 4 times. Now your task is to prove that n propositions are all equivalent, and that your friend has made the M deduction for you (what is known about each deduction), at least a few more deduction to complete the proof?
First Tarjan to find the strong connected components, contraction points, statistics of the degree of access to each point. With a node in the read as 0,b node out of 0, the answer is Max (A, A, b).
Code:
#include <iostream>#include<cstdio>#include<cmath>#include<vector>#include<string.h>using namespaceStd;vector<int>g[20001];intn,m,t,i,j,x,y,dfn[20001],dfs_clock,low[20001],in0[20001],out0[20001],c[20001],a,b,l,f[20001],cnt;voidDfsintu) {Dfn[u]=low[u]=++Dfs_clock; c[++l]=u; for(intI=0; I<g[u].size (); + +i)if(!Dfn[g[u][i]]) {DFS (g[u][i]); Low[u]=min (Low[u],low[g[u][i]]); }Else if(!f[g[u][i]]) low[u]=min (Low[u],dfn[g[u][i]]); if(low[u]==Dfn[u]) {CNT++; while(c[l]!=u) f[c[l--]]=CNT; F[c[l--]]=CNT; }}intMain () {scanf ("%d",&t); for(intu=0; u<t;++u) {scanf ("%d%d",&n,&m); for(i=1; i<=n;++i) g[i].clear (); for(i=1; i<=m;++i) {scanf ("%d%d",&x,&y); G[x].push_back (y); } memset (DFN,0,sizeof(DFN)); memset (Low,0,sizeof(low)); memset (In0,0,sizeof(In0)); memset (Out0,0,sizeof(out0)); Memset (F,0,sizeof(f)); Memset (c,0,sizeof(c)); A=0; b=0; l=0; cnt=0;d fs_clock=0; for(i=1; i<=n;++i)if(!Dfn[i]) DFS (i); for(i=1; i<=n;++i) for(j=0; J<g[i].size (); + +j)if(f[g[i][j]]!=F[i]) {In0[f[g[i][j] ]++; Out0[f[i]]++; } for(i=1; i<=cnt;++i) { if(!in0[i]) a++; if(!out0[i]) b++; } if(cnt==1) printf ("0\n");Elseprintf"%d\n", Max (A, b)); } return 0;}LA4287
La4287--tarjan