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 ...
随机推荐
- Weka算法Clusterers-DBSCAN源代码分析
假设说世界上仅仅能存在一种基于密度的聚类算法的话.那么它必须是DBSCAN(Density-based spatial clustering of applications with noise).D ...
- redis 源代码分析(一) 内存管理
一,redis内存管理介绍 redis是一个基于内存的key-value的数据库,其内存管理是很重要的,为了屏蔽不同平台之间的差异,以及统计内存占用量等,redis对内存分配函数进行了一层封装,程序中 ...
- [Redux] Implementing combineReducers() from Scratch
The combineReducers function we used in previous post: const todoApp = combineReducers({ todos, visi ...
- Handler Looper 原理 详解
演示代码 public class MainActivity extends ListActivity { private TextView tv_info; private CalT ...
- Windows 右键快速运行命令行
原文见:右键命令行 - yacper - 博客园 方法一:配置文件夹选项 1 打开人任意文件夹,[工具] --> [文件夹选项] --> [文件类型] --> [(无)资料夹] -- ...
- java开发软件的安装
jdk+eclipse+svn+maven+mysql+tomcat7.0+sublime安装包和jar插件 配置管理工具-SVN http://download.csdn.net/detail/u0 ...
- window程序设计1
int WINAPI WinMain(HINSTANCE HInstance,HINSTANCE HPreInstance,LPSTR szCmdLine,int CmdShown) { Massag ...
- 在TCP协议下的数据传送
本人小白菜逼一枚,,,,刚建立博客,也写不了太深入的,就写点上课的笔记什么的.有错误希望广大博友指出,我一定虚心学习接收改正. 我的新浪邮箱:liudaohui0805@sina.com 我的QQ邮箱 ...
- 12个用得着的JQuery代码片段
1. 导航菜单背景切换效果 在项目的前端页面里,相对于其它的导航菜单,激活的导航菜单需要设置不同的背景.这种效果实现的方式有很多种,下面是使用JQuery实现的一种方式: <ul id='nav ...
- Zepto源码笔记(一)
最近在研究Zepto的源码,这是第一篇分析,欢迎大家继续关注,第一次写源码笔记,希望大家多指点指点,第一篇文章由于首次分析原因不会有太多干货,希望后面的文章能成为各位大大心目中的干货. Zepto是一 ...