hdu 4635 Strongly connected (tarjan)
题意:给一个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)的更多相关文章
- HDU 4635 Strongly connected (Tarjan+一点数学分析)
Strongly connected Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) ...
- HDU 4635 - Strongly connected(2013MUTC4-1004)(强连通分量)
t这道题在我们队属于我的范畴,最终因为最后一个环节想错了,也没搞出来 题解是这么说的: 最终添加完边的图,肯定可以分成两个部X和Y,其中只有X到Y的边没有Y到X的边,那么要使得边数尽可能的多,则X部肯 ...
- hdu 4635 Strongly connected(强连通)
考强连通缩点,算模板题吧,比赛的时候又想多了,大概是不自信吧,才开始认真搞图论,把题目想复杂了. 题意就是给你任意图,保证是simple directed graph,问最多加多少条边能使图仍然是si ...
- HDU 4635 Strongly connected (2013多校4 1004 有向图的强连通分量)
Strongly connected Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- HDU 4635 Strongly connected ——(强连通分量)
好久没写tarjan了,写起来有点手生,还好1A了- -. 题意:给定一个有向图,问最多添加多少条边,让它依然不是强连通图. 分析:不妨考虑最大时候的临界状态(即再添加一条边就是强连通图的状态),假设 ...
- HDU 4635 Strongly connected(强连通分量,变形)
题意:给出一个有向图(不一定连通),问最多可添加多少条边而该图仍然没有强连通. 思路: 强连通分量必须先求出,每个强连通分量包含有几个点也需要知道,每个点只会属于1个强连通分量. 在使图不强连通的前提 ...
- HDU 4635 Strongly connected(强连通分量缩点+数学思想)
题意:给出一个图,如果这个图一开始就不是强连通图,求出最多加多少条边使这个图还能保持非强连通图的性质. 思路:不难想到缩点转化为完全图,然后找把它变成非强连通图需要去掉多少条边,但是应该怎么处理呢…… ...
- HDU 4635:Strongly connected(强连通)
http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给出n个点和m条边,问最多能添加几条边使得图不是一个强连通图.如果一开始强连通就-1.思路:把图分成 ...
- hdu 4635 Strongly connected 强连通缩点
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4635 题意:给你一个n个点m条边的图,问在图不是强连通图的情况下,最多可以向图中添多少条边,若图为原来 ...
随机推荐
- XSS第二节,XSS左邻右舍
昨天的文章中引用了OWASP2013年的江湖排名,今天来看一下TOP中XSS的左邻右舍都是谁,先看一下他们的大名,再进一步介绍 [以下主要翻译自https://www.owasp.org/index. ...
- Android开发 ADB server didn't ACK, failed to start daemon解决方案
有时候在打开ddms的时候,会看到adb会报如题的错误,解决方案是打开任务管理器,(ctrl+shift+esc),然后关掉adb.exe的进程,重启eclipse就ok了. 还有许多无良商家开发的垃 ...
- Tcp 数据对象传输接口对象设计
输入是一个对象inputObj,接口对象.Send(inputObj),对端接收之后解包成outputObj(与inputObj应相同),触发onPackageReceive事件 事件 public ...
- C++菱形继承的构造函数
网上搜了很多,大多是关于菱形虚继承的构造函数应该怎么写,或者就是最简单的,四个类都不带参数的构造函数. 本文旨在记录一下困扰了博主1h的问题,非常浅显,有帮助固然好,如果侮辱谁的智商还见谅,当然无限欢 ...
- HTML与CSS入门——第二章 发布Web内容
知识点: 1.使用文本编辑器创建一个基本的HTML文件的方法 2.使用FTP将文件传送到你的Web服务器的方法 3.文件在Web服务器上应该存储的位置 4.在没有Web服务器的情况下分发Web内容的方 ...
- Canvas Api简介1
canvas canvas 其实对于HTML来说很简单,只是一个标签元素而已,自己并没有行为,但却把一个绘图 API 展现给客户端 JavaScript 以使脚本能够把想绘制的东西都绘制到一块画布上, ...
- 提示框的优化之自定义Toast组件之(二)Toast组件的业务逻辑实现
在java下org.socrates.mydiary.activity下LoginActivity下自定义一个方法showCustomerToast() public class LoginAct ...
- iOS方法类:CGAffineTransform的使用
CoreGraphics框架中的CGAffineTransform类可用于设定UIView的transform属性,控制视图的缩放.旋转和平移操作: 另称放射变换矩阵,可参照线性代数的矩阵实现方式0. ...
- UITextView(文本视图) 学习之初体验
UITextView文本视图相比与UITextField直观的区别就是UITextView可以输入多行文字并且可以滚动显示浏览全文.常见UITextView使用在APP的软件简介.内容详情显示.小说阅 ...
- slave延迟原因及优化方法
转载叶总:http://imysql.com/2015/04/12/mysql-optimization-case-howto-resolve-slave-delay.shtml 一般而言,slave ...