首页 > 代码库 > HDU 4635 Strongly connected
HDU 4635 Strongly connected
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4635
解题思路:
题目大意是你能最多能添加多少边,使的这个图不是强连通图。其临界条件是差一条边成强连通图。
可以把图分成两个强连通图,左边的一个强连通分量点个数为y,右边一个强连通分量的个数为x。
然后x的所有点都与y的所有点都有x->y连线,没有y-x的连线。这就是最终答案。
x+y=n
x×(x-1)+y×(y-1)+x×y-m
化简的 n×n-x×y-n-m,很明显只有|x-y|的绝对值越大,最终结果就越大。
最后我们用Tarjan算法,进行缩点后可能形成现在这样的图
很明显只有入度,或出度为零的点才能选做x,或y。
实现代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int MAXN=100010; 8 9 struct Edge{ 10 int to,next; 11 }edges[MAXN]; 12 13 int head[MAXN],tot; 14 15 void init(){ 16 memset(head,-1,sizeof(head)); 17 tot=0; 18 } 19 20 void addEdge(int u,int v){ 21 edges[tot].to=v; 22 edges[tot].next=head[u]; 23 head[u]=tot++; 24 } 25 26 int DFN[MAXN],LOW[MAXN],Stack[MAXN],NUM[MAXN],Belong[MAXN]; 27 bool Instack[MAXN]; 28 int scc,Index,top; 29 30 void Tarjan(int u){ 31 DFN[u]=LOW[u]=++Index; 32 Stack[top++]=u; 33 Instack[u]=true; 34 35 int v; 36 for(int i=head[u];i!=-1;i=edges[i].next){ 37 v=edges[i].to; 38 39 if(!DFN[v]){ 40 Tarjan(v); 41 if(LOW[u]>LOW[v]) 42 LOW[u]=LOW[v]; 43 }else if(Instack[v]&&LOW[u]>DFN[v]) LOW[u]=DFN[v]; 44 } 45 46 if(LOW[u]==DFN[u]){ 47 scc++; 48 do{ 49 v=Stack[--top]; 50 NUM[scc]++; 51 Instack[v]=false; 52 Belong[v]=scc; 53 }while(v!=u); 54 } 55 } 56 57 int in[MAXN],out[MAXN]; 58 void solve(long long n,long long m){ 59 memset(DFN,0,sizeof(DFN)); 60 memset(NUM,0,sizeof(NUM)); 61 memset(Instack,0,sizeof(Instack)); 62 top=Index=scc=0; 63 64 for(int i=1;i<=n;i++) 65 if(!DFN[i]) 66 Tarjan(i); 67 68 if(scc==1){ 69 cout<<-1<<endl; 70 return; 71 } 72 73 memset(in,0,sizeof(in)); 74 memset(out,0,sizeof(out)); 75 76 for(int i=1;i<=n;i++) 77 for(int j=head[i];j!=-1;j=edges[j].next){ 78 int v=edges[j].to; 79 if(Belong[i]!=Belong[v]){ 80 out[Belong[i]]++; 81 in[Belong[v]]++; 82 } 83 } 84 85 long long ans=0; 86 87 for(int i=1;i<=scc;i++){ 88 if(in[i]==0||out[i]==0){ 89 ans=max(ans,(n*n-(n-NUM[i])*NUM[i]-n-m)); 90 } 91 } 92 93 //注意数据溢出的情况 94 95 printf("%lld\n",ans); 96 } 97 98 99 int main(){ 100 int T; 101 scanf("%d",&T); 102 for(int i=1;i<=T;i++){ 103 104 init(); 105 int n,m; 106 scanf("%d%d",&n,&m); 107 for(int j=0;j<m;j++){ 108 int u,v; 109 scanf("%d%d",&u,&v); 110 addEdge(u,v); 111 } 112 printf("Case %d: ",i); 113 solve(n,m); 114 115 } 116 }
HDU 4635 Strongly connected
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。