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. Tengine 四层代理:

    Tengine 四层代理: 1 ) 安装tengine ( nginx1.9 以上版本 编译以后要支持stream 模块) 1.1 ) tengine(nginx) 一定要是nginx-1.9.X 以 ...

  2. 深入汇编指令理解Java关键字volatile

    volatile是什么 volatile关键字是Java提供的一种轻量级同步机制.它能够保证可见性和有序性,但是不能保证原子性 可见性 对于volatile的可见性,先看看这段代码的执行 flag默认 ...

  3. /usr/bin/ld: cannot find -lc

    yum install glibc-static [root@test chkrootkit-0.50]# make sensecc -static -o strings-static strings ...

  4. 【Linux】rsh进程缓慢问题处理

    环境CentOS 6.5 由于项目上线时间很长,服务器持续很久没有关机重启过,随后发现rsh反应特别慢 rsh登陆服务器的反应最慢时候3分钟才可以建立链接,登陆之后查看服务器负载是否正常,查看cpu, ...

  5. 【Oracle】查询执行慢的sql

    查询执行最慢的sql select * from (select sa.SQL_TEXT, sa.SQL_FULLTEXT, sa.EXECUTIONS "执行次数", round ...

  6. HarmonyOS三方件开发指南(5)——Photoview组件

    PhotoView使用说明 1.  PhotoView功能介绍1.1 组件介绍:        PhotoView是一个继承自Image的组件,不同之处在于:它可以进行图击放大功能,手势缩放功能(暂无 ...

  7. python—打开图像文件报错

    今天使用python打开一张图像文件的时候报错了 UnicodeDecodeError: 'gbk' codec can't decode byte 0xff in position 0: illeg ...

  8. fileinput模块用法

    fileinput模块功能: 提供拼接一个或多个文本文件的功能,可以通过使用for循环来读取一个或多个文本文件的所有行,从而进行逐行处理(如进行显示.替换.添加行号等). 其功能类似于linux命令的 ...

  9. 利用sklearn进行字典&文本的特征提取

    写在前面 这篇博客主要内容: 应用DictVectorizer实现对类别特征进行数值化.离散化 应用CountVectorizer实现对文本特征进行数值化 特征提取API sklearn.featur ...

  10. 1.5V升3.3V芯片电路图,稳压3.3V供电MCU模块等

    干电池1.5V可以升到3.3V,通过PW5100干电池升压IC,于外围3个元件:2个电容和一个电感即可组成1.5V升3.3V的电路系统. 干电池属于低能量的电池产品,不过一般使用到干电池的产品也是输出 ...