hdu 3836 Equivalent Sets(tarjan+缩点)
To prove two sets A and B are equivalent, we can first prove A is a subset of B, and then prove B is a subset of A, so finally we got that these two sets are equivalent.
You are to prove N sets are equivalent, using the method above: in each step you can prove a set X is a subset of another set Y, and there are also some sets that are already proven to be subsets of some other sets.
Now you want to know the minimum steps needed to get the problem proved.
The input file contains multiple test cases, in each case, the first line contains two integers N <= and M <= .
Next M lines, each line contains two integers X, Y, means set X in a subset of set Y.
For each case, output a single integer: the minimum steps needed.
Case 2: First prove set 2 is a subset of set 1 and then prove set 3 is a subset of set 1.
把tarjan复习了一遍
题目描述:将题目中的集合转换为顶点,A集合是B集合的子集,转换为一条有向边<A,B>,即题目给我们一个有向图,问最少需要添加多少条边使之成为强连通图。
解题思路:通过tarjan算法找出图中的所有强连通分支,并将每一个强连通分支缩成一个点(因为强连通分量本身已经满足两两互相可达)。
要使缩点后的图成为强连通图,每个顶点最少要有一个入度和一个出度,一条边又提供一个出度和一个入度。
所以可以通过统计没有入度的顶点数 noInDegree 和 没有出度的顶点数 noOutDegree。
所需要添加的边数就是noInDegree和noOutDegree中的最大值。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<vector>
using namespace std;
#define N 20006
#define inf 1<<26
int n,m;
struct Node
{
int from;
int to;
int next;
}edge[N<<];
int tot;//表示边数,边的编号
int head[N];
int vis[N];
int tt;
int scc;
stack<int>s;
int dfn[N],low[N];
int col[N]; void init()//初始化
{
tt=;
tot=;
memset(head,-,sizeof(head));
memset(dfn,-,sizeof(dfn));
memset(low,,sizeof(low));
memset(vis,,sizeof(vis));
memset(col,,sizeof(col));
} void add(int s,int u)//邻接矩阵函数
{
edge[tot].from=s;
edge[tot].to=u;
edge[tot].next=head[s];
head[s]=tot++;
} void tarjan(int u)//tarjan算法找出图中的所有强连通分支
{
dfn[u] = low[u]= ++tt;
vis[u]=;
s.push(u);
int cnt=;
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].to;
if(dfn[v]==-)
{
// sum++;
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v]==)
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
int x;
scc++;
do{
x=s.top();
s.pop();
col[x]=scc;
vis[x]=;
}while(x!=u);
}
} int main()
{
while(scanf("%d%d",&n,&m)== && n+m)
{ init(); scc=;//scc表示强连通分量的个数
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);//构造邻接矩阵
}
for(int i=;i<=n;i++)
{
if(dfn[i]==-)
{
tarjan(i);
}
}
//printf("%d\n",scc); int inde[N];
int outde[N];
memset(inde,,sizeof(inde));
memset(outde,,sizeof(outde));
for(int i=;i<tot;i++)
{
int a=edge[i].from;
int b=edge[i].to;
if(col[a]!=col[b])
{
inde[col[b]]++;
outde[col[a]]++;
}
} int ans1=;
int ans2=;
for(int i=;i<=scc;i++)
{
if(inde[i]==)
{
ans1++;
}
if(outde[i]==)
{
ans2++;
}
}
if(scc==)
{
printf("0\n");
continue;
}
printf("%d\n",max(ans1,ans2)); }
return ;
}
hdu 3836 Equivalent Sets(tarjan+缩点)的更多相关文章
- hdu 3836 Equivalent Sets trajan缩点
Equivalent Sets Time Limit: 12000/4000 MS (Java/Others) Memory Limit: 104857/104857 K (Java/Other ...
- [tarjan] hdu 3836 Equivalent Sets
主题链接: http://acm.hdu.edu.cn/showproblem.php? pid=3836 Equivalent Sets Time Limit: 12000/4000 MS (Jav ...
- hdu 3836 Equivalent Sets
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3836 Equivalent Sets Description To prove two sets A ...
- hdu 3836 Equivalent Sets(强连通分量--加边)
Equivalent Sets Time Limit: 12000/4000 MS (Java/Others) Memory Limit: 104857/104857 K (Java/Other ...
- hdu——3836 Equivalent Sets
Equivalent Sets Time Limit: 12000/4000 MS (Java/Others) Memory Limit: 104857/104857 K (Java/Other ...
- hdu - 3836 Equivalent Sets(强连通)
http://acm.hdu.edu.cn/showproblem.php?pid=3836 判断至少需要加几条边才能使图变成强连通 把图缩点之后统计入度为0的点和出度为0的点,然后两者中的最大值就是 ...
- HDU3836 Equivalent Sets (Tarjan缩点+贪心)
题意: 给你一张有向图,问你最少加多少条边这张图强连通 思路: 缩点之后,如果不为1个点,答案为出度为0与入度为0的点的数量的最大值 代码: #include<iostream> #inc ...
- HDU - 3836 Equivalent Sets (强连通分量+DAG)
题目大意:给出N个点,M条边.要求你加入最少的边,使得这个图变成强连通分量 解题思路:先找出全部的强连通分量和桥,将强连通分量缩点.桥作为连线,就形成了DAG了 这题被坑了.用了G++交的,结果一直R ...
- hdoj 3836 Equivalent Sets【scc&&缩点】【求最少加多少条边使图强连通】
Equivalent Sets Time Limit: 12000/4000 MS (Java/Others) Memory Limit: 104857/104857 K (Java/Other ...
随机推荐
- I/O多路转接 --- UNIX环境高级编程
I/O多路转接技术:先构造一张有关描述符的列表,然后调用一个函数,知道这些描述符中的一个已准备好进行I/O时,给函数才返回.在返回时,它告诉进程哪些描述符已准备好可以进行I/O. poll.selec ...
- 转载: C#: Left outer joins with LINQ
I always considered Left Outer Join in LINQ to be complex until today when I had to use it in my app ...
- JS中事件代理与委托
在javasript中delegate这个词经常出现,看字面的意思,代理.委托.那么它究竟在什么样的情况下使用?它的原理又是什么?在各种框架中,也经常能看到delegate相关的接口.这些接口又有什么 ...
- thinkphp学习资料
http://www.5idev.com/p-thinkphp_auto_function_callback.shtml
- Linux命令初步了解
知识点: 1.虚拟控制台: 在系统启动时直接进入字符工作方式后,系统提供了多个(默认为6个)虚拟控制台.每个虚拟控制台可以相互独立使用,互不影响. 可以使用Alt+F1~Alt+F6进行多个虚拟控制台 ...
- Fragment的生命周期&同一Activity下不同Fragment之间的通信
Android开发:碎片Fragment完全解析(2) Fragment的生命周期 和Activity一样,Fragment也有自己的生命周期,理解Fragment的生命周期非常重要,我们通过代码的方 ...
- Codeforces Round #318(Div 1) 573A, 573B,573C
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud 这场的前两题完全是手速题...A题写了7分钟,交的时候已经500+了,好在B题出的 ...
- js 获取mac地址
js 获取mac地址 function MacInfo(){ var locator =new ActiveXObject ("WbemScripting.SWbemLocator" ...
- 在Yii2中使用Pjax导致Yii2内联脚本载入失败的问题
当我用defunkt/jquery-pjax载入Yii2的ActiveForm时发生一个错误,正常情况下是 ActiveForm的两个js应该先载入,而实际情况是 typeError:JQuery(. ...
- pyqt5和qt-designer结合
在ubuntu中我们安装了python3-pyqt5这个包后就可以用pyqt5编程了,但是只能用纯代码写窗体,很麻烦.我们要用qt-designer来设计窗体. 我们通过新立得安装qt4-design ...