1 //题意:
2 //给你一个有向图,如果这个图是一个强连通图那就直接输出-1
3 //否则,你就要找出来你最多能添加多少条边,在保证添加边之后的图依然不是一个强连通图的前提下
4 //然后输出你最多能添加的边的数目
5 //
6 //题解:
7 //1、判断是否是强连通图你可以看一下有几个点的low[x]==dfn[x],如果只有一个,那这个图就是一个强连通图
8 //2、
9 //假如我们有两个子图,我们可以让这两个子图中每一个图内都连上有向边(把子图内部连成完全图)。然后再在这两个子图之间连上一条有向边
10 //这样的话它仍然不是一个强连通图,因为这两个图之间的边只能进不能出(即,图与图之间是用单向边连接的)
11 //这个子图是什么?
12 //这个子图就是缩点之后的点的数目,因为缩点之后肯定可以保证里面没有环。但是这个点可能是由许多点缩成的,这个点
13 //内部就是一个子图,除了这个点之外所有点是另一个子图。
14 //之后我们可以先让原图进行缩点,这样图中就没有了环,然后我们再找出来哪个点的出度等于1或者入读等于1
15 //因为只有这样的点才是决定是否这个图能变成强连通图的关键
16 //为什么要找出入或者入度为0的点,因为作为一个强连通图是没有任何一个点出度或入度为0(反证法)
17 #include<stdio.h>
18 #include<string.h>
19 #include<iostream>
20 #include<algorithm>
21 #include<map>
22 #include<math.h>
23 #include<set>
24 #include<vector>
25 #include<queue>
26 using namespace std;
27 typedef long long ll;
28 const int maxn=100005;
29 const int mod=26;
30 const int INF=0x3f3f3f3f;
31 const int block=300;
32 struct edge
33 {
34 ll u,v,next;
35 } e[100005];
36 ll dfn[maxn],low[maxn],stacks[maxn],belong[maxn],in[maxn],out[maxn],g[maxn];
37 ll head[maxn],visit[maxn],cnt,tot,index,scc;
38 void init()
39 {
40 memset(in,0,sizeof(in));
41 memset(out,0,sizeof(out));
42 memset(g,0,sizeof(g));
43 memset(head,-1,sizeof(head));
44 memset(low,0,sizeof(low));
45 memset(dfn,0,sizeof(dfn));
46 memset(visit,0,sizeof(visit));
47 memset(belong,0,sizeof(belong));
48 cnt=tot=index=scc=0;
49 }
50 void add_edge(ll x,ll y)
51 {
52 e[cnt].u=x;
53 e[cnt].v=y;
54 e[cnt].next=head[x];
55 head[x]=cnt++;
56 }
57 ll tarjan(ll x)
58 {
59 dfn[x]=low[x]=++tot;
60 stacks[++index]=x;
61 visit[x]=1;
62 for(ll i=head[x]; i!=-1; i=e[i].next)
63 {
64 if(!dfn[e[i].v])
65 {
66 tarjan(e[i].v);
67 low[x]=min(low[x],low[e[i].v]);
68 }
69 else if(visit[e[i].v])
70 {
71 low[x]=min(low[x],dfn[e[i].v]);
72 }
73 }
74 if(dfn[x]==low[x])
75 {
76 scc++;
77 do
78 {
79 g[scc]++;
80 visit[stacks[index]]=0;
81 belong[stacks[index]]=scc;
82 index--;
83 }
84 while(x!=stacks[index+1]);
85 }
86 }
87 int main()
88 {
89 ll n,m,t,p=0;
90 scanf("%lld",&t);
91 while(t--)
92 {
93 init();
94 scanf("%lld%lld",&n,&m);
95 cnt=0;
96 for(ll i=1; i<=n; ++i)
97 {
98 head[i]=-1;
99 visit[i]=0;
100 dfn[i]=0;
101 low[i]=0;
102 }
103 ll mm=m;
104 while(mm--)
105 {
106 ll x,y;
107 scanf("%lld%lld",&x,&y);
108 add_edge(x,y);
109 }
110 ll flag=0;
111 for(ll i=1;i<=n;++i)
112 {
113 if(!dfn[i])
114 tarjan(i);
115 }
116 if(scc==1)
117 {
118 printf("Case %lld: -1\n",++p);
119 }
120 else
121 {
122 for(ll i=0; i<cnt; ++i)
123 {
124 ll fx=belong[e[i].u];
125 ll fy=belong[e[i].v];
126 if(fx!=fy)
127 {
128 out[fx]++;
129 in[fy]++;
130 }
131 }
132 ll ans=0,sum=0;
133 for(ll i=1; i<=scc; ++i)
134 {
135 if(in[i]==0 || out[i]==0)
136 {
137 sum=0;
138 //printf("%lld**\n",g[i]);
139 ll temp=n-g[i];
140 //printf("%lld*\n",temp);
141 sum+=temp*(temp-1);
142 //printf("%lld**\n",sum);
143 sum+=g[i]*(g[i]-1);
144 //printf("%lld***\n",sum);
145 sum+=g[i]*temp;
146 //printf("%lld****\n",sum);
147 sum-=m;
148 ans=max(ans,sum);
149 }
150
151 }
152 printf("Case %lld: %lld\n",++p,ans);
153 }
154 }
155 return 0;
156 }

连通图和完全图的区别:
n个顶点的完全图有n(n-1)/2条边;而连通图则不一定,但至少有n-1条边。举个例子,
四个顶点的完全图有6条边,也就是四条边加上2条对角线;而连通图可以只包含周围四条边就可以了。

Strongly connected HDU - 4635 原图中在保证它不是强连通图最多添加几条边的更多相关文章

  1. Strongly connected HDU - 4635(判断强连通图 缩点)

    找出强联通块,计算每个连通块内的点数.将点数最少的那个连通块单独拿出来,其余的连通块合并成一个连通分量. 那么假设第一个连通块的 点数是 x  第二个连通块的点数是 y 一个强连通图(每两个点之间,至 ...

  2. G - Strongly connected - hdu 4635(求连通分量)

    题意:给你一个图,问最多能添加多少条边使图仍为不是强连通图,如果原图是强连通输出 ‘-1’ 分析:先把求出连通分量进行缩点,因为是求最多的添加边,所以可以看成两部分 x,y,只能一部分向另外一部分连边 ...

  3. kuangbin专题 专题九 连通图 Strongly connected HDU - 4635

    题目链接:https://vjudge.net/problem/HDU-4635 题目:有向图,给定若干个连通图,求最多还能添加几条边,添完边后,图仍然要满足 (1)是简单图,即没有重边或者自环 (2 ...

  4. 强连通图(最多加入几条边使得图仍为非强连通图)G - Strongly connected HDU - 4635

    题目链接:https://cn.vjudge.net/contest/67418#problem/G 具体思路:首先用tarjan缩点,这个时候就会有很多个缩点,然后再选取一个含有点数最少,并且当前这 ...

  5. HDU 4635 Strongly connected ——(强连通分量)

    好久没写tarjan了,写起来有点手生,还好1A了- -. 题意:给定一个有向图,问最多添加多少条边,让它依然不是强连通图. 分析:不妨考虑最大时候的临界状态(即再添加一条边就是强连通图的状态),假设 ...

  6. [HDU4635] Strongly connected

    传送门:>Here< 题意:给出一张DAG,问最多添加几条边(有向)使其强连通分量个数大于1 解题思路 最少添加几条边使其强连通我们是知道的,非常简单,就是入度为0的点与出度为0的点的较大 ...

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

    Strongly connected Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

  8. hdu 4635 Strongly connected 强连通缩点

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给你一个n个点m条边的图,问在图不是强连通图的情况下,最多可以向图中添多少条边,若图为原来 ...

  9. HDU 4635 Strongly connected (强连通分量+缩点)

    <题目链接> 题目大意: 给你一张有向图,问在保证该图不能成为强连通图的条件下,最多能够添加几条有向边. 解题分析: 我们从反面思考,在该图是一张有向完全图的情况下,最少删去几条边能够使其 ...

随机推荐

  1. 使用nodejs和express搭建http web服务

    目录 简介 使用nodejs搭建HTTP web服务 请求nodejs服务 第三方lib请求post 获取http请求的正文 Express和使用express搭建http web服务 express ...

  2. 7.prometheus之查询API

    一.格式概述 二.表达式查询 2.1 Instant queries(即时查询) 2.2 范围查询 三.查询元数据 3.1 通过标签匹配器找到度量指标列表 3.2 获取标签名 3.3 查询标签值 四. ...

  3. Ice系列--强大如我IceGrid

    前言 IceGrid是一个提供服务定位和服务激活的组件,但它的功能远不止于此.从它的命名可以看出它的设计理念-网格计算(grid computing).网格计算被定义为由一系列关联的廉价计算机组成的计 ...

  4. 【Azure App Service For Container】创建ASP.NET Core Blazor项目并打包为Linux镜像发布到Azure应用服务

    欢迎使用 Blazor!Blazor 是一个使用 .NET 生成交互式客户端 Web UI 的框架: 使用 C# 代替 JavaScript 来创建信息丰富的交互式 UI. 共享使用 .NET 编写的 ...

  5. STL_string容器

    一.string概念 string是STL的字符串类型,通常用来表示字符串.而在使用string之前,字符串通常是用char*表示的.string与char*都可以用来表示字符串,那么二者有什么区别. ...

  6. 学习Java第三天

    方法重载:同一个类,方法名相同,参数不同(个数不同,类型不同,顺序不同),判断是否重载,只看方法名和参数,跟返回值无关. IDEA查看方法源代码:Crtl + 鼠标左键 进制表示 Java数值默认为十 ...

  7. 《awk中文手册》-本人参考官方手册翻译

    01. 简介 AWK是一个文本(面向行和列)处理工具,同时它也是一门脚本语言. AWK其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernigha ...

  8. 计算机网络安全 —— 报文摘要算法 ME5 (三)

    一.报文摘要算法基本概念 使用加密通常可达到报文鉴别的目的,因为伪造的报文解密后一般不能得到可理解的内容.但简单采用这种方法,计算机很难自动识别报文是否被篡改.另外,对于不需要保密而只需要报文鉴别的网 ...

  9. nginx proxy pass redirects ignore port

    nginx proxy pass redirects ignore port $host in this order of precedence: host name from the request ...

  10. Java泛型机制

    泛型程序设计 1.泛型程序设计的起源? 泛型是JDK1.5增加的新特性. 2.使用泛型的好处? 使用泛型机制编写的代码比那些杂乱使用Object变量,然后再进行强制类型转换的代码具有更好的安全性和可读 ...