好久没写tarjan了,写起来有点手生,还好1A了- -。

  题意:给定一个有向图,问最多添加多少条边,让它依然不是强连通图。

  分析:不妨考虑最大时候的临界状态(即再添加一条边就是强连通图的状态),假设这时候的边的数量是F,那么答案就是F-m(m是一开始边的数量)。因此,F越大,答案越大。那么,怎么考虑F的值呢?最后的状态一定是这样的:整个图不是强连通的,但是他的两个分部x和y都是强连通的,并且其中任意一个分量(不妨设其为x),到另外一个分量(y),x中的每一个点到y中的每一个点都有边,而且,y中的每一个点到x中的每一个点都没有边;另外,x和y内部任意两点间都是有边的。这样的话任意添加一条边都会使得原图变成一个强连通图(因为再添加边只能是y中一点到x一点,这样整个图中任意两点间都可达了)。那么我们不妨设x中点的个数为a,y中点的个数为b=n-a(共有n个点),因此F=a*(a-1)+b*(b-1)+a*b(x到y的边)。这样,ans=F-m,化简得到ans=n*n-a*b-n-m。对a和b进行基本不等式可知,他们相等时乘积最大,因此他们相差最大时ans最大(也可以直接枚举任意两个强连通分量来得到答案)。另外要注意的一点是,x和y必须一个有任意一个是入度或者出度为0的,这样的话,才能使得他们构造成为F的状态。还想提的一点是,一个点也能成为强连通分量。

  具体见代码:

 #include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <stack>
using namespace std;
const int inf = 0x3f3f3f3f;
typedef long long ll;
typedef pair<int,int> pii;
const int N = + ; int n,m,dfs_clock,dfn[N],low[N];
int belong[N],scc_cnt,cnt[N],in[N],out[N];
stack<int> S;
vector<int> G[N]; void init()
{
for(int i=;i<=n;i++) G[i].clear();
dfs_clock = ;
memset(dfn,,sizeof(dfn));
memset(belong,,sizeof(belong));
scc_cnt = ;
memset(cnt,,sizeof(cnt));
memset(in,,sizeof(in));
memset(out,,sizeof(out));
} void tarjan(int u)
{
dfn[u]=low[u]=++dfs_clock;
S.push(u);
for(int i=;i<G[u].size();i++)
{
int v = G[u][i];
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!belong[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
scc_cnt++;
int num = ;
for(;;)
{
num ++;
int x = S.top();S.pop();
belong[x] = scc_cnt;
if(x==u) break;
}
cnt[scc_cnt] = num;
}
} void solve()
{
for(int i=;i<=n;i++)
{
if(!dfn[i]) tarjan(i);
} for(int i=;i<=n;i++)
{
int x = belong[i];
for(int j=;j<G[i].size();j++)
{
int v = G[i][j];
if(belong[i] == belong[v]) continue; int y = belong[v];
out[x]++;
in[y]++;
}
} ll ans = ;
for(int i=;i<=scc_cnt;i++)
{
if(in[i] && out[i]) continue; int a = cnt[i];
int b = n-a;
ans = max(ans,(ll)n*n-(ll)a*b-n-m);
}
if(scc_cnt == ) ans = -;
cout << ans << endl;
} int main()
{
int T;
scanf("%d",&T);
for(int kase=;kase<=T;kase++)
{
init();
printf("Case %d: ",kase);
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
}
solve();
}
}

HDU 4635 Strongly connected ——(强连通分量)的更多相关文章

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

    题意 给定一个N个点M条边的简单图,求最多能加几条边,使得这个图仍然不是一个强连通图. 思路 2013多校第四场1004题.和官方题解思路一样,就直接贴了~ 最终添加完边的图,肯定可以分成两个部X和Y ...

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

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

  3. hdu 4635 Strongly connected 强连通缩点

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

  4. HDU 4635 Strongly connected(强连通)经典

    Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  5. hdu 4635 Strongly connected 强连通

    题目链接 给一个有向图, 问你最多可以加多少条边, 使得加完边后的图不是一个强连通图. 只做过加多少条边变成强连通的, 一下子就懵逼了 我们可以反过来想. 最后的图不是强连通, 那么我们一定可以将它分 ...

  6. HDU 4635 Strongly connected (2013多校4 1004 有向图的强连通分量)

    Strongly connected Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  7. HDU 4635 Strongly connected(强连通分量,变形)

    题意:给出一个有向图(不一定连通),问最多可添加多少条边而该图仍然没有强连通. 思路: 强连通分量必须先求出,每个强连通分量包含有几个点也需要知道,每个点只会属于1个强连通分量. 在使图不强连通的前提 ...

  8. HDU 4635 - Strongly connected(2013MUTC4-1004)(强连通分量)

    t这道题在我们队属于我的范畴,最终因为最后一个环节想错了,也没搞出来 题解是这么说的: 最终添加完边的图,肯定可以分成两个部X和Y,其中只有X到Y的边没有Y到X的边,那么要使得边数尽可能的多,则X部肯 ...

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

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

随机推荐

  1. JavaScript随机验证码

    利用canvas制作一个随机验证码: 1.clearRect:context.clearRect(x,y,width,height);清空给定矩形内的指定像素 2.fillStyle:设置画笔的颜色 ...

  2. vue 实现textarea展示时自动换行

    利用 v-html 展示 str.replace(/\n|\r\n/g, '<br>') 数据 完美解决

  3. IEAD工具教你创建maven项目

    之前一直用的是其他的开发工具,maven到目前为止也就用了3个月,今天又时间整理一些初期的使用方法,仅供参照. 为什么要用maven 原因很简单,因为使用maven,会使得项目非常容易管理. 举个例子 ...

  4. 【3】Git命令

    个人推荐的Git知识学习网站:https://git-scm.com . git常用操作图 init -> add -> commit -> remote -> push 初始 ...

  5. redis写入性能测试

    import timeit import redis def clock(func): def clocked(*args, **kwargs): t0 = timeit.default_timer( ...

  6. 008.建立主从表(sql实例)

    CREATE TABLE info(snumb int primary key identity(1,1),sname varchar(20),sex bit,birthday datetime ch ...

  7. 修改IDEA关闭标签页的快捷键

    IDEA原先关闭标签页的快捷键是Ctrl + F4 ,操作起来很不方便,而我们通常习惯于用 Ctrl + W 关闭浏览器的标签页,所以,也可以将关闭IDEA标签页的快捷键修改为Ctrl + W,具体步 ...

  8. SQLSERVER EXISTS IN 优化

    数据量: 首先我们看看待优化的SQL: 简单的分析下来发现: EXISTS 这部分执行比较慢,我们来看一下, 这种写法比较便于理解,但是执行起来却很慢.既然这里慢,我们就要优化这部分. 首先我是想把拼 ...

  9. set调用add报错:

    Map<String, String> goodsStandMap = new HashMap<>();goodsStandMap.put("key1", ...

  10. Airtest 支持的手机,系统等环境

    据个人经验,Airtest 支持的以下设备会跑的比较666 Android 平台 华为荣耀9青春版 版本:8.0.0 型号:LLD-AL10 评价:自动化运行最6 华为 荣耀10青春版 版本:9.0. ...