标签:pop code include pac i++ mem string math class
n个点m条边
最少需要几条边变成强连通图
设有a个结点的入读为0, b个结点的出度为0, 则 max{a, b}就是答案。 注意特殊情况: 当原图已经强连通时, 答案是0而不是1.
加一条边少一个入度出度
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<queue> 5 #include<math.h> 6 #include<stack> 7 8 using namespace std; 9 10 #define MAXN 100010 11 12 int head[MAXN],low[MAXN],dfn[MAXN],f[MAXN],in[MAXN],out[MAXN]; 13 bool vis[MAXN]; 14 int cnt,k,num; 15 struct edg 16 { 17 int fr,to,next; 18 19 }x[MAXN]; 20 21 void add(int u,int v) 22 { 23 x[cnt].next=head[u]; 24 x[cnt].fr=u; 25 x[cnt].to=v; 26 head[u]=cnt++; 27 } 28 stack<int>s; 29 30 void dfs(int u) 31 { 32 low[u]=dfn[u]=k++; 33 vis[u]=1; 34 s.push(u); 35 int i; 36 for(i=head[u];i!=-1;i=x[i].next) 37 { 38 int t=x[i].to; 39 if(!dfn[t]) 40 { 41 dfs(t); 42 low[u]=min(low[u],low[t]); 43 } 44 else if(vis[t]) 45 low[u]=min(low[u],dfn[t]); 46 } 47 if(low[u]==dfn[u]) 48 { 49 num++; 50 while(!s.empty()) 51 { 52 int now=s.top(); 53 s.pop(); 54 vis[now]=0; 55 f[now]=num; 56 if(now==u)break; 57 } 58 } 59 } 60 61 int main() 62 { 63 int n,m,t; 64 65 while(scanf("%d%d",&n,&m)!=EOF) 66 { 67 int i; 68 memset(head,-1,sizeof(head)); 69 cnt=0; 70 for(i=1;i<=m;i++) 71 { 72 int a,b; 73 scanf("%d%d",&a,&b); 74 add(a,b); 75 } 76 k=1; 77 num=0; 78 memset(dfn,0,sizeof(dfn)); 79 memset(low,0,sizeof(low)); 80 memset(vis,0,sizeof(vis)); 81 memset(f,0,sizeof(f)); 82 for(i=1;i<=n;i++) 83 { 84 if(!dfn[i]) 85 dfs(i); 86 } 87 memset(head,-1,sizeof(head)); 88 int en=cnt; 89 memset(in,0,sizeof(in)); 90 memset(out,0,sizeof(out)); 91 92 for(i=0;i<en;i++) 93 { 94 int u,v; 95 u=f[x[i].fr]; 96 v=f[x[i].to]; 97 if(u!=v) 98 { 99 add(u,v); 100 out[u]++; 101 in[v]++; 102 } 103 } 104 int a,b; 105 a=b=0; 106 107 for(i=1;i<=num;i++) 108 { 109 if(in[i]==0) 110 a++; 111 if(out[i]==0) 112 b++; 113 } 114 if(num==1) 115 printf("0\n"); 116 else 117 printf("%d\n",max(a,b)); 118 } 119 return 0; 120 }
标签:pop code include pac i++ mem string math class
原文地址:http://www.cnblogs.com/cherryMJY/p/6058804.html