hdu 2767 Proving Equivalences
Proving Equivalences
题意:输入一个有向图(强连通图就是定义在有向图上的),有n(1 ≤ n ≤ 20000)个节点和m(0 ≤ m ≤ 50000)条有向边;问添加几条边可使图变成强连通图;
强连通分量:对于分量中的任意两个节点,都存在一条有向的路径(顺序不同,表示的路径不同);说白了,就是任意两点都能形成一个环(但不是说只有一个环)
思路:使用Tarjan算法 (讲解得很好)即可容易地在得到在一个强连通分量中设置每个点所属的强连通分量的标号;即得到所谓的缩点;
之后就是合并所有连通分量,使得形成一个强连通分量。这个合并就是在连通分量中加有向边,即将所缺少的总入度和缺少的总的出度比较,取大的即可;(可浪费不能缺)
实现细节:开始认为可以在Tarjan中之中得到每个强连通分量的入度和出度;即在循环枚举v时再加一个else来看这条连通分量之间的边,设置出度,入度在标记点的连通分量标号时处理。但是里面涉及到好几种情况的点;不好分析与调试;还是在全部处理完了再遍历边来看是否为不同连通分量的连边;更清晰一些;
PS:要特判id == 1的情况,不然题给就是一个强连通分量,ans = 0,但是处理in[],out[]时会认为该连通分量需要和其他的连通分量连边,导致答案为1...
还有就是点的入度和出度都是对所属的连通分量而言的,开始输入时不需要处理;
时间复杂度为O(n+m)
// 265MS 4792K
#include<bits/stdc++.h>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS1(a) memset(a,-1,sizeof(a))
const int MAXN = ;
int head[MAXN],tot;
struct edge{
int to,w,Next;
}e[MAXN];
void ins(int a,int b,int w = )
{
e[++tot].Next = head[a];
e[tot].to = b;
e[tot].w = w;
head[a] = tot;
}
const int N = ;
int pre[N],dfs_clock,low[N];
int belong[N],id;
stack<int> S;
bool stk[N];
void Tarjan(int u)
{
pre[u] = low[u] = ++dfs_clock;
S.push(u);
stk[u] = true;
int v;//点u所在连通分量的出度;
for(int i = head[u];i;i = e[i].Next){
v = e[i].to;
if(pre[v] == ){
Tarjan(v);
low[u] = min(low[u],low[v]);
}else if(stk[v]){
low[u] = min(low[u],pre[v]);
}
}
if(pre[u] == low[u]){//强连通分量的根节点
++id;
do{
v = S.top();
S.pop();stk[v] = false;
belong[v] = id;
}while(v != u);
}
}
int in[N],out[N];
int main()
{
int T,kase = ;
scanf("%d",&T);
while(T--){
MS0(head);tot = ;
int n,m,a,b;
scanf("%d%d",&n,&m);
rep0(i,,m){
scanf("%d%d",&a,&b);
ins(a,b);
}
id = dfs_clock = ;
rep1(i,,n) pre[i] = low[i] = belong[i] = ;
rep1(i,,n)if(pre[i] == )
Tarjan(i);
rep1(i,,id)
in[i] = out[i] = ;//并不是原图输入的入度与出度;而是缩点之后的强连通分量;
rep1(u,,n){//在缩点完了之后再对边进行处理,看是否符合入度出度关系;
for(int index = head[u];index;index = e[index].Next){
int v = e[index].to;
if(belong[u] != belong[v]){//***强连通分量之间的连边
in[belong[v]]++,out[belong[u]]++;
}
}
}
int in_deg = ,out_deg = ;
if(id == ){// ** WA了很多次。。
puts("");
continue;
}
rep1(j,,id){
if(in[j] == ) in_deg++;
if(out[j] == ) out_deg++;
}
printf("%d\n",max(in_deg,out_deg));
}
return ;
}
hdu 2767 Proving Equivalences的更多相关文章
- HDU 2767 Proving Equivalences (强联通)
pid=2767">http://acm.hdu.edu.cn/showproblem.php?pid=2767 Proving Equivalences Time Limit: 40 ...
- HDU 2767 Proving Equivalences(至少增加多少条边使得有向图变成强连通图)
Proving Equivalences Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- HDU 2767 Proving Equivalences (Tarjan)
Proving Equivalences Time Limit : 4000/2000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other ...
- hdu 2767 Proving Equivalences(tarjan缩点)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2767 题意:问最少加多少边可以让所有点都相互连通. 题解:如果强连通分量就1个直接输出0,否者输出入度 ...
- HDU 2767 Proving Equivalences(强连通 Tarjan+缩点)
Consider the following exercise, found in a generic linear algebra textbook. Let A be an n × n matri ...
- hdu 2767 Proving Equivalences 强连通缩点
给出n个命题,m个推导,问最少添加多少条推导,能够使全部命题都能等价(两两都能互推) 既给出有向图,最少加多少边,使得原图变成强连通. 首先强连通缩点,对于新图,每一个点都至少要有一条出去的边和一条进 ...
- HDU 2767:Proving Equivalences(强连通)
题意: 一个有向图,问最少加几条边,能让它强连通 方法: 1:tarjan 缩点 2:采用如下构造法: 缩点后的图找到所有头结点和尾结点,那么,可以这么构造:把所有的尾结点连一条边到头结点,就必然可以 ...
- hdoj 2767 Proving Equivalences【求scc&&缩点】【求最少添加多少条边使这个图成为一个scc】
Proving Equivalences Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- HDU 2767.Proving Equivalences-强连通图(有向图)+缩点
Proving Equivalences Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
随机推荐
- Android Studio无法启动 打开, Android Studio gradle下载不了
Google在2013年I/O大会上发布了Android Studio,AndroidStudio是一个基于IntelliJ思想的新的Android开发工具.下面介绍一下Android Studio安 ...
- SQL SERVER 2005 同步复制
what SQL SERVER2005复制是在不同数据库间保持数据结构和数据内容同步更新的一种方案. 由三部分构成: 发布服务器:包含了需要被发布的数据库,也就是需要向其它数据源分发内容的源数据库. ...
- RESTful HTTP实践
http://www.infoq.com/cn/articles/designing-restful-http-apps-roth 摘要: 本文对RESTful HTTP的基础原理做了一个概览,探讨了 ...
- appscan 安全漏洞修复办法
appscan 安全漏洞修复办法http://www.automationqa.com/forum.php?mod=viewthread&tid=3661&fromuid=21
- 深入浅出ECharts系列(一)地图+散点图
深入浅出ECharts系列(一) 目标 本次教程的目标是实现“微博签到点亮中国”散点图,实现结果如图: 2. 准备工作 a) 首先下载ECharts插件,你可以根据自己的实际需求选择你 ...
- 关于Apache Commons-Lang的总结
部分转载至:http://linhongyu.blog.51cto.com/6373370/1553329 一.前言 Java码农不识Apache,敲尽一生也枉然.旗下的开源项目众多,各个都是吊炸天. ...
- SharpDevelop 编译时,任务失败,因为未找到“resgen.exe”的解决方法
在git clone sprite的项目,在本地编译的时候,会出现 任务失败,因为未找到“resgen.exe”,或未安装正确的 Microsoft Windows SDK.任务正在注册表项 HKEY ...
- js如何实现一定时间后去执行一个函数
js如何实现一定时间后去执行一个函数:在实际需要中可能需要规定在指定的时间之后再去执行一个函数以达成期望的目的,这也就是一个定时器效果,恰好在js中就已经给定了这样的一个函数setTimeout(), ...
- 20160526-20160531mybatis入门进阶
mybatis第二天 高级映射 查询缓存 和spring整合 课程复习: mybatis是什么? mybatis是一人持久层框架,mybatis是一个不完全的ORM框架.sql语句需要程序员自己去编 ...
- Android IntentService使用
因为多数启动服务不必同时处理多个请求(在多线程情景下会很危险),所以使用IntentService类实现服务是很好的选择.本经验将通过继承IntentService输出当前时间教大家如何使用Inten ...