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. Memcached repcached 高可用

    Memcached + repcached 高可用环境 repcached 就是一个让memcached的机器能够互为主从,前端可以加一台HAProxy,后端两台memcached互为主从后,写入任何 ...

  2. 编译安装PHP - 7.3.16

    编译安装PHP - 7.3.16 1 ) 安装依赖包: yum install -y gcc gcc-c++ make zlib zlib-devel pcre pcre-devel libjpeg ...

  3. maven生命周期与插件

    目录 Maven生命周期 clean default site 命令与对应周期 插件与绑定 插件目标 插件绑定 内置绑定 自定义绑定 插件配置 本文主要是针对<maven实战>书中关键知识 ...

  4. 3610:20140827:161308.483 No active checks on server: host [192.168.1.10] not found

    3610:20140827:161308.483 No active checks on server: host [192.168.1.10] not found

  5. scp传文件夹

    scp -r /root/backupdb/2014-08-15(文件夹)    root@192.168.1.98:/root(目录)

  6. kubernets集群的安全防护(上)

    一  了解认证机制 1.1   API的服务器在接收来自客户端的请求的时候会对发起的用户进行几个步骤 认证插件进行认证,确认发起的用户是外部用户,还是集群中的某个命名空间里面的pod 确认用户属于哪个 ...

  7. kubernets之namespace

    一 命名空间的介绍以及作用 1  概念 为了方便不同部门之间对kubernets集群的使用,并且对其进行有效的隔离,kubernets提供了一种资源隔离手段,通过将各种不同资源分组到 一个区域,并且统 ...

  8. paramiko模块简单用法

    最简单最基本的用法 1 #__*__coding:utf-8__*__ 2 import paramiko 3 hostname = '192.168.1.1' 4 username = 'root' ...

  9. PyTorch 于 JupyterLab 的环境准备

    PyTorch 是目前主流的深度学习框架之一,而 JupyterLab 是基于 Web 的交互式笔记本环境.于 JupyterLab 我们可以边记笔记的同时.边执行 PyTorch 代码,便于自己学习 ...

  10. git 基本命令和操作

    设置全局用户名+密码 $ git config --global user.name 'runoob' $ git config --global user.email test@runoob.com ...