考强连通缩点,算模板题吧,比赛的时候又想多了,大概是不自信吧,才开始认真搞图论,把题目想复杂了。

题意就是给你任意图,保证是simple directed graph,问最多加多少条边能使图仍然是simple directed graph,即 无重边且整个图非强连通。

容易想到把所有的点分成两个集合,只要在同一个方向上把所有边都连上就很理想。那么点该如何分配呢?差值尽可能的大,因为总的边数不单单是两集合之间的边,还要算上集合内部全部的边,注意集合内部是在保证不出现重边的条件下的所有的边。

令总点数为n,一个集合的点数为k,则两个集合内的边数分别为 k*(k-1),(n-k)*(n-k-1)条,而两集合之间的边共有 k*(n-k)条,答案就是三个值相加再减去已有的m条边。

注意:虽然最理想的是一个集合里只有一个点,但实际是一个强连通的最小点集,见最后一组样例,而且可能都在一棵树上,所以只要缩点后找到出度或入度为0的分量中点数最小的就可以了。

 #include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; const int MAXN=; struct Edge{
int v,next;
int vis;
Edge(){}
Edge(int _v,int _next):v(_v),next(_next),vis(){}
}edge[MAXN]; int head[MAXN],tol;
int stk[MAXN],dfn[MAXN],low[MAXN],top,TT;
int sub[MAXN],scc,num[MAXN]; int a[MAXN],b[MAXN];
int in[MAXN],out[MAXN]; void add(int u,int v)
{
edge[tol]=Edge(v,head[u]);
head[u]=tol++;
} void tarjan(int u)
{
int v;
dfn[u]=low[u]=++TT;
stk[top++]=u;
for(int i=head[u];i!=-;i=edge[i].next)
{
v=edge[i].v;
if(edge[i].vis)
continue;
edge[i].vis=;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}else if(!sub[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
scc++;
int s=;
do{
v=stk[--top];
sub[v]=scc;
s++;
}while(v!=u);
num[scc]=s;
}
} void init()
{
tol=;
memset(head,-,sizeof(head)); memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(sub,,sizeof(sub));
} int main()
{
int T,n,m;
scanf("%d",&T);
for(int K=;K<=T;K++)
{
scanf("%d%d",&n,&m); init();
for(int i=;i<m;i++)
{
scanf("%d%d",&a[i],&b[i]);
add(a[i],b[i]);
} TT=;top=;scc=;
for(int i=;i<=n;i++)
if(!dfn[i])
tarjan(i); if(scc==){
printf("Case %d: -1\n",K);
continue;
} memset(in,,sizeof(in));
memset(out,,sizeof(out));
for(int i=;i<m;i++)
{
if(sub[a[i]]!=sub[b[i]]){
out[sub[a[i]]]++;
in[sub[b[i]]]++;
}
}
int min=;
for(int i=;i<=scc;i++)
{
if(!in[i]||!out[i])
if(num[min]>num[i])
min=i;
}
int k=num[min];
printf("Case %d: %d\n",K,k*(k-)+(n-k)*(n-k-)+k*(n-k)-m); }
return ;
}

hdu 4635 Strongly connected(强连通)的更多相关文章

  1. hdu 4635 Strongly connected 强连通缩点

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

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

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

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

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

  4. hdu 4635 Strongly connected 强连通

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

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

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

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

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

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

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

  8. HDU 4635 Strongly connected (Tarjan+一点数学分析)

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

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

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

随机推荐

  1. 1293: [SCOI2009]生日礼物 - BZOJ

    Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩 ...

  2. python logging TimedRotatingFileHandler 作用

    max backup count这样的参数,即打印的日志文件数量超过这个阈值,发生rotate,从最老的文件开始清理 未亲测.

  3. WEB前端常用的测试工具

    一.QUnit 前端测试工具 QUnit是一个强大的JavaScript单元测试框架,该框架是由jQuery团队的成员所开发,并且是jQuery的官方测试套件.Qunit是Jquery的单元测试框架, ...

  4. Oracle/PLSQL: Creating Functions

    In Oracle, you can create your own functions. 译:在ORACLE中,你可以创建你自己的方法. The syntax for a function is: ...

  5. How does database indexing work?

    When data is stored on disk based storage devices, it is stored as blocks of data. These blocks are ...

  6. java基础知识回顾之java Thread类学习(四)--java多线程安全问题(锁)

    上一节售票系统中我们发现,打印出了错票,0,-1,出现了多线程安全问题.我们分析为什么会发生多线程安全问题? 看下面线程的主要代码: @Override public void run() { // ...

  7. Intent (一)

    1,简介 Intent 是一种消息传递机制,可以理解为一种对消息的封装,执行某操作的抽象描述,可用于应用程序内部及应用程序之间 其组成包括: 要执行的动作(action) 如VIEW_ACTION(查 ...

  8. ZOJ 3791 An Easy Game(DP)

    题目链接 题意 : 给你两个长度为N的字符串,将第一个字符串每次只能变化M个,问变换K次之后变成第二个字符串一共有几种方法. 思路 : DP.dp[i][j]表示变了 i 次之后有j个不一样的字母的方 ...

  9. hdu 4578 Transformation 线段树

    没什么说的裸线段树,注意细节就好了!!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> ...

  10. CLR 读书笔记

    http://www.cnblogs.com/wang_yb/tag/CLR%20via%20C%23%E7%AC%94%E8%AE%B0/