Strongly connected

hdu4635:http://acm.hdu.edu.cn/showproblem.php?pid=4635

题意:给你一个有向图,然后问你最多可以加多少条边,是的原图不是一个强连通图。

题解:这一题确实不会,图论做的太少了,一下是一个人分析,觉得分析的很不错,代码也是看别人的。

首先强连通缩点,缩点之后,最终添加完边的图,肯定可以分成两个部X和Y,其中只有X到Y的边没有Y到X的边;  *那么要使得边数尽可能的多,则X部肯定是一个完全图,Y部也是,同时X部中每个点到Y部的每个点都有一条边;  *假设X部有x个点,Y部有y个点,则x+y=n; 同时边数F=x*y+x*(x-1)+y*(y-1),然后去掉已经有了的边m,则为答案; 当x+y为定值时,二者越接近,x*y越大,所以要使得边数最多,那么X部和Y部的点数的个数差距就要越大; 对于给定的有向图缩点,对于缩点后的每个点,如果它的出度或者入度为0,那么它才有可能成为X部或者Y部; 然后找出最大值即可;

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 const int N=200010;
  7 const int M=400010;
  8 const int INF=0xffffffff;
  9 struct Edge{
 10     int to,next;
 11 } edge[M];
 12
 13 int  n,m,cnt,dep,top,atype;
 14 int  dfn[N],low[N],vis[N],head[N],st[N],belong[N],in[N],out[N],sum[N];
 15 //sum[i]记录第i个连通图的点的个数,in[i],out[i],表示缩点之后点的入度和初度。
 16 void init(){
 17       cnt=dep=top=atype=0;
 18     memset(head,-1,sizeof(head));
 19     memset(dfn,0,sizeof(dfn));
 20     memset(low,0,sizeof(low));
 21     memset(vis,0,sizeof(vis));
 22     memset(belong,0,sizeof(belong));
 23     memset(in,0,sizeof(in));
 24     memset(out,0,sizeof(out));
 25     memset(sum,0,sizeof(sum));
 26 }
 27 void addedge(int u,int v){
 28     edge[cnt].to=v;
 29     edge[cnt].next=head[u];
 30     head[u]=cnt++;
 31 }
 32
 33 void Tarjan(int u){
 34     dfn[u]=low[u]=++dep;
 35     st[top++]=u;
 36     vis[u]=1;
 37     for(int i=head[u]; i!=-1; i=edge[i].next){
 38         int v=edge[i].to;
 39         if(!dfn[v]){
 40             Tarjan(v);
 41             low[u]=min(low[u],low[v]);
 42         }
 43         else if(vis[v]){
 44             low[u]=min(low[u],dfn[v]);
 45         }
 46     }
 47     int j;
 48     if(dfn[u]==low[u]){
 49         atype++;
 50         do{
 51             j=st[--top];
 52             belong[j]=atype;
 53             sum[atype]++;   //记录每个连通分量中点的个数
 54             vis[j]=0;
 55         }
 56         while(u!=j);
 57     }
 58 }
 59
 60 long long solve(){
 61     if(n==1){
 62         return -1;
 63     }
 64     init();
 65     int u,v;
 66     for(int i=0; i<m; i++){
 67         scanf("%d%d",&u,&v);
 68         addedge(u,v);
 69     }
 70     for(int i=1; i<=n; i++)
 71         if(!dfn[i])
 72             Tarjan(i);
 73     if(atype==1){
 74         return -1;
 75     }
 76     for(int u=1; u<=n; u++)
 77         for(int i=head[u]; i!=-1; i=edge[i].next){
 78             int v=edge[i].to;
 79             if(belong[u]!=belong[v]){
 80                 out[belong[u]]++;
 81                 in[belong[v]]++;
 82             }
 83         }
 84     long long  tmp=100000000;
 85     for(int i=1; i<=atype; i++)
 86         if(in[i]==0 || out[i]==0){
 87          tmp=min(tmp,(long long)sum[i]);
 88         }
 89     return  tmp*(tmp-1)+(n-tmp)*(n-tmp-1)+tmp*(n-tmp)-m;
 90 }
 91 int cas;
 92 int main(){
 93     scanf("%d",&cas);
 94     int tt=1;
 95     while(cas--){
 96         scanf("%d%d",&n,&m);
 97         printf("Case %d: %I64d\n",tt++,solve());
 98     }
 99     return 0;
100 }

Strongly connected

时间: 2024-11-05 18:52:52

Strongly connected的相关文章

PTA Strongly Connected Components

Write a program to find the strongly connected components in a digraph. Format of functions: void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) ); where Graph is defined as the following: typedef struct VNode *PtrToVNode; struct VNode

HDU 4635 —— Strongly connected——————【 强连通、最多加多少边仍不强连通】

Strongly connected Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4635 Description Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the edges you can

HDU 4635 Strongly connected (有向图的强连通分量)

Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the edges you can add that the grap

[tarjan] hdu 4635 Strongly connected

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4635 Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1568    Accepted Submission(s): 654 Problem Description Give a simple dir

HDU 4635 Strongly connected(强连通)经典

Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1828    Accepted Submission(s): 752 Problem Description Give a simple directed graph with N nodes and M edges. Please tell me

[email&#160;protected] Strongly Connected Component

Strongly Connected Components A directed graph is strongly connected if there is a path between all pairs of vertices. A strongly connected component (SCC) of a directed graph is a maximal strongly connected subgraph. For example, there are 3 SCCs in

【CodeForces】913 F. Strongly Connected Tournament

[题目]F. Strongly Connected Tournament [题意]给定n个点(游戏者),每轮游戏进行下列操作: 1.对于游戏者i和j(i<j),有p的概率i赢j(反之j赢i),连边从赢者向输者,从而得到一个有向完全图,这些点视为进行了一轮游戏. 2.对于其中点数>1的强连通分量再次进行过程1,直至不存在点数>1的强连通分量为止. 给定n和p,求所有点进行的游戏轮数之和,2<=n<=2000. [算法]数学概率,期望DP [题解]参考:官方题解Hello 201

【CF913F】Strongly Connected Tournament 概率神题

[CF913F]Strongly Connected Tournament 题意:有n个人进行如下锦标赛: 1.所有人都和所有其他的人进行一场比赛,其中标号为i的人打赢标号为j的人(i<j)的概率为$p=a\over b$.2.经过过程1后我们相当于得到了一张竞赛图,将图中所有强联通分量缩到一起,可以得到一个链,然后对每个大小>1的强联通分量重复过程1.3.当没有大小>1的强连通分量时锦标赛结束. 现在给出n,a,b,求期望比赛的场数. $n\le 2000,a<b\le 1000

6-10 Strongly Connected Components (30分)

Write a program to find the strongly connected components in a digraph. Format of functions: void StronglyConnectedComponents( Graph G, void (*visit)(Vertex V) ); where Graph is defined as the following: typedef struct VNode *PtrToVNode; struct VNode