题意:给一个n个顶点m条弧的简单有向图(无环无重边),求最多能够加入多少条弧使得加入后的有向图仍为简单有向图且不是一个强连通图。假设给的简单有向图本来就是强连通图,那么输出-1.



分析:

1.用tarjan算法求出强连通分量的个数,假设个数为1,那么输出-1,结束,否则运行2

2.如果将一些强连通分量合并为有n1个顶点简单全然图1,而将剩下的强连通分量合并为n2个顶点的简单全然图2,跨这两个简单全然图的弧的方向仅仅能是单向的,如果m1为全然图1内部的弧的数量,m2为为全然图2内部的弧的数量。m3为跨这两个简单全然图的弧的数量,那么

ans=n1*(n1-1)-m1+n2*(n2-1)-m2+n1*n2-m3  ----------------------------------------------------1式

 n1+n2=n                                                            ----------------------------------------------------2式

 m1+m2+m3=m                                                 ----------------------------------------------------3式

 n*n=(n1+n2)(n1+n2)=n1*n1+n2*n2+2*n1*n2 -----------------------------------------------------4式

所以

ans=n*n-m-n-n1*n2=n*n-m-n-n1*(n-n1)

ans要最大,所以n1*(n-n1)要最小。同一时候要跨图1。图2的弧要单向,

所以在跨图1,图2的弧要单向的情况下。n1尽量小。


代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 100005
#define INF 1<<30
using namespace std; typedef struct ArcNode
{
int adjvex;//该弧所指向的顶点的位置
struct ArcNode * nextarc;//指向下一条弧的指针
} ArcNode; typedef struct VNode
{
int vertex;
//int In_deg,Out_deg;
int belong;
ArcNode * firstarc;
} VNode; VNode V[MAX];
int DFN[MAX],Stack[MAX],low[MAX];
int top,index,bcnt;
bool instack[MAX];
long long n,m;
int Min;
int cnt;
int k;
int edge[MAX][2]; void init()
{
int a,b;
ArcNode * p;
for(int i=1; i<=n; i++)
{
V[i].vertex=i;
//V[i].In_deg=V[i].Out_deg=0;
V[i].firstarc =NULL;
}
for(int i=0; i<m; i++)
{
scanf("%d%d",&a,&b);
// V[a].Out_deg++;
// V[b].In_deg++;
edge[i][0]=a;
edge[i][1]=b;
p=(ArcNode*)malloc(sizeof(ArcNode));
p->adjvex =b;
p->nextarc =V[a].firstarc ;
V[a].firstarc =p;
}
} void DFS_tarjan(int i)
{
int j;
ArcNode * p;
DFN[i]=low[i]=++index;
Stack[++top]=i;
instack[i]=true;
p=V[i].firstarc ;
while(p!=NULL)
{
j=p->adjvex;
if(!DFN[j])
{
DFS_tarjan(j);
if(low[j]<low[i])//Low(u)为u的子树可以追溯到的最早的栈中节点的次序号
low[i]=low[j];
}
else if(instack[j]&&DFN[j]<low[i])//Low(u)为u可以追溯到的最早的栈中节点的次序号
low[i]=DFN[j];
p=p->nextarc;//
}
if(DFN[i]==low[i])
{
bcnt++;
cnt=0;
int INDEG=0;
int OUTDEG=0;
do
{
j=Stack[top--];//出栈,j是为该强连通分量中一个顶点
instack[j]=false;
//INDEG+=V[j].In_deg;
//OUTDEG+=V[j].Out_deg;
V[j].belong=bcnt;
cnt++;
}
while(i!=j);
for(int kkk=0;kkk<m;kkk++)
{
if(V[edge[kkk][0]].belong==bcnt&&V[edge[kkk][1]].belong!=bcnt)
{
OUTDEG++;
}
if(V[edge[kkk][0]].belong!=bcnt&&V[edge[kkk][1]].belong==bcnt)
INDEG++;
}
if(Min>cnt&&(INDEG==0||OUTDEG==0))
{
Min=cnt;
}
}
} void FREE()
{
ArcNode * p;
ArcNode * q;
for(int i=1; i<=n; i++)
{
p=V[i].firstarc;
while(p!=NULL)
{
q=p;
p=p->nextarc;
free(q);
}
}
} void solve()
{
int i;
top=index=bcnt=0;
memset(DFN,0,sizeof(DFN));
memset(instack,false,sizeof(instack));
for(i=1; i<=n; i++)
{
if(!DFN[i])
DFS_tarjan(i);
}
//printf("%d\n",bcnt);
FREE();
if(bcnt==1)
{
printf("Case %d: -1\n",k);
return;
}
long long ans=n*n-n-m-(Min*(n-Min));
//printf("%d\n",Min);
printf("Case %d: %lld\n",k,ans);
} int main()
{
int t;
scanf("%d",&t);
for(k=1; k<=t; k++)
{
scanf("%lld%lld",&n,&m);
Min=INF;
init();
solve();
}
return 0;
}

hdu 4635 Strongly connected (tarjan)的更多相关文章

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

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

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

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

  3. hdu 4635 Strongly connected(强连通)

    考强连通缩点,算模板题吧,比赛的时候又想多了,大概是不自信吧,才开始认真搞图论,把题目想复杂了. 题意就是给你任意图,保证是simple directed graph,问最多加多少条边能使图仍然是si ...

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

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

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

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

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

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

  7. HDU 4635 Strongly connected(强连通分量缩点+数学思想)

    题意:给出一个图,如果这个图一开始就不是强连通图,求出最多加多少条边使这个图还能保持非强连通图的性质. 思路:不难想到缩点转化为完全图,然后找把它变成非强连通图需要去掉多少条边,但是应该怎么处理呢…… ...

  8. HDU 4635:Strongly connected(强连通)

    http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给出n个点和m条边,问最多能添加几条边使得图不是一个强连通图.如果一开始强连通就-1.思路:把图分成 ...

  9. hdu 4635 Strongly connected 强连通缩点

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

随机推荐

  1. High bridge, low bridge(离散化, 前缀和)

    High bridge, low bridge Q:There are one high bridge and one low bridge across the river. The river h ...

  2. [Protractor] Use protractor to catch errors in the console

    For any reason, there is an error in your code, maybe something like undefined error. Protractor sti ...

  3. 在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6578352 在数字科技日新月异的今天,软件和硬 ...

  4. el表达式判断是否相等

    <c:if test="${order.baofang eq 0 }"> 无包间 </c:if> <c:if test="${order.b ...

  5. asp.net UpdatePanel 不能局部刷新问题汇总

    1.web.config 配置问题.   关于web.config的配置方面网上有很多资料参考,按照其方法做即可实现. 2.网站 Framework 版本变化造成不能局部刷新问题    版本更新时,会 ...

  6. OutputCache各参数的说明

    OutputCache各参数的说明 Duration 缓存时间,以秒为单位,这个除非你的Location=None,可以不添加此属性,其余时候都是必须的. Location Location当被设置为 ...

  7. Android中获取apk基本信息

    一 PackageManager可以获得的所有包节点信息: 1,所有节点的基类:PackageItemInfo: 2,PackageInfo:package的全面信息,与AndroidManifest ...

  8. iOS 判断设备是否越狱

    我们在开发过程中,需要知道设备是否越狱,在网上查看很多资料,为此封装一些判断的方法. 上代码,不解释: .h文件 #import <Foundation/Foundation.h> @in ...

  9. 解决iOS9苹果将原http协议改成了https协议问题

    解决方法: 在info.plist 加入key <key>NSAppTransportSecurity</key> <dict> <key>NSAllo ...

  10. java实例变量及方法调用顺序

    public class Base { private String name="base"; public Base(){ sayHello(); } void sayHello ...