题意:给你一个连通图,问你最多加多少条边,还能保证该图不是强连通图。
对整个图求强连通分量,然后对图缩点,记录一下缩点之后每隔点包含的原来的点的个数,找出最少的那个点,然后对这个点建成完全图,对另外的所有点建成完全图。然后+两个点建边-所有原来的遍就好了。
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635
1 #include <iostream> 2 #include <vector> 3 #include <queue> 4 #include <string.h> 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include <stack> 8 9 using namespace std; 10 const int maxn = 50050; 11 12 struct edge 13 { 14 int u,v,val; 15 }; 16 int dfn[10050],low[10050],belong[10050],inst[10050]; 17 int pnum[10050]; 18 int in[10050]; 19 int inside[10050]; 20 int out[10050]; 21 vector<edge> edges,es; 22 vector<int>g[maxn]; 23 vector<int>ng[maxn]; 24 stack<int>st; 25 int bcnt,cnt,dfsclock; 26 int max(int a,int b) 27 { 28 if(a > b) 29 return a; 30 31 return b; 32 } 33 void init(int n) 34 { 35 int i; 36 for(i =0;i <= n;i++) 37 g[i].clear(); 38 39 edges.clear(); 40 41 es.clear(); 42 dfsclock = 0;bcnt = cnt = 0; 43 return ; 44 } 45 void addedge(int u,int v,int val) 46 { 47 edges.push_back((edge){u,v,1}); 48 g[u].push_back(cnt); 49 cnt++; 50 51 return ; 52 } 53 void tarjan(int i) 54 { 55 int j; 56 dfn[i] = low[i] = ++dfsclock; 57 inst[i] = 1; 58 st.push(i); 59 60 for(j = 0;j < g[i].size();j++) 61 { 62 edge e; 63 e = edges[g[i][j]]; 64 int v; 65 v = e.v; 66 if(!dfn[v]) 67 { 68 tarjan(v); 69 low[i] = min(low[i],low[v]); 70 } 71 else if(inst[v] && dfn[v] < low[i]) 72 low[i] = dfn[v]; 73 } 74 if(dfn[i] == low[i]) 75 { 76 bcnt++; 77 do 78 { 79 j = st.top(); 80 st.pop(); 81 inst[j] = 0; 82 belong[j] = bcnt; 83 84 } 85 while(j != i); 86 } 87 88 } 89 void tarjans(int n) 90 { 91 int i; 92 bcnt = dfsclock = 0; 93 while(!st.empty())st.pop(); 94 memset(dfn,0,sizeof(dfn)); 95 96 memset(inst,0,sizeof(inst)); 97 memset(belong,0,sizeof(belong)); 98 for(i = 1;i <= n;i++) 99 if(!dfn[i])tarjan(i); 100 } 101 int main() 102 { 103 int n,m; 104 int t; 105 106 scanf("%d",&t); 107 int cas = 0; 108 while(t--) 109 { 110 scanf("%d %d",&n,&m); 111 int a,b,i; 112 init(n); 113 for(i = 0;i < m;i++) 114 { 115 scanf("%d %d",&a,&b); 116 addedge(a,b,1); 117 struct edge x; 118 x.u = a; 119 x.v = b; 120 x.val = 1; 121 es.push_back(x); 122 123 } 124 tarjans(n); 125 126 printf("Case %d: ",++cas); 127 if(bcnt == 1) 128 { 129 puts("-1"); 130 continue; 131 } 132 int pnum[10050]; 133 int in[10050]; 134 int out[10050]; 135 memset(pnum,0,sizeof(pnum)); 136 memset(in,0,sizeof(in)); 137 memset(out,0,sizeof(in)); 138 memset(inside,0,sizeof(inside)); 139 for(i = 1;i <= n;i++) 140 { 141 pnum[belong[i]]++; 142 } 143 144 for(i = 0;i < m;i++) 145 { 146 int u,v; 147 u = es[i].u; 148 v = es[i].v; 149 if(belong[u] != belong[v]) 150 { 151 out[belong[u]]++; 152 in[belong[v]]++; 153 } 154 } 155 __int64 ans; 156 ans = n; 157 158 for(i = 1;i <= bcnt;i++) 159 { 160 if(in[i] == 0 || out[i] == 0) 161 { 162 if(ans > pnum[i]) 163 ans = pnum[i]; 164 } 165 } 166 167 ans = (__int64)(n-ans)* (__int64)(n-ans-1)+ (__int64)ans* (__int64)(ans-1)+ (__int64)ans*(__int64)(n-ans)- (__int64)(m); 168 // printf("bcnt %d p %d ams %d ansi %d ",bcnt,pnum[ansi],ans,ansi); 169 170 printf("%I64d ",ans); 171 172 } 173 return 0; 174 }