hdu3836
来源:互联网 发布:超级基因优化液微盘 编辑:程序博客网 时间:2024/04/29 23:07
Equivalent Sets
Time Limit: 12000/4000 MS (Java/Others) Memory Limit: 104857/104857 K (Java/Others)Total Submission(s): 3751 Accepted Submission(s): 1308
Problem Description
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.
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.
Input
The input file contains multiple test cases, in each case, the first line contains two integers N <= 20000 and M <= 50000.
Next M lines, each line contains two integers X, Y, means set X in a subset of set Y.
Next M lines, each line contains two integers X, Y, means set X in a subset of set Y.
Output
For each case, output a single integer: the minimum steps needed.
Sample Input
4 03 21 21 3
Sample Output
42
一个图,含有n个点,p条边(单向),问最少加几条边可以使该图成为强连通图,
可以用Tarjan算法,或者Kosaraju算法,算出含有几个强连通分量,这几个强连通分量有有几个出度为0有几个入度为0,输出多的那个(a个出度为0的分量,b个入度为0 的分量,输出max(a,b));
解释:强连通分量里每个点都是可以互相到达的,每个强连通分量之间要想都可以互相到达,每个分量必须至少含有一个出度一个入度,也就是说,出度为0的边必须给他加一条边指向其他分量,如果入度为0 ,那么要给他加一条边指向他,所以出 输出max(a,b)
注意:如果只有一个强连通分量,或者n==1,输出0,因为一个强连通分量表示该图就是强连通的了,,n==1时自身可以到达自身,也是强连通图,
#include <iostream>#include <stdio.h>#include <string.h>#include <math.h>using namespace std;const int maxn=20020;const int maxe=50040;struct edge{ int x,y,next;} e[maxe];int num[maxn];///每个联通分量含有点的个数int g[maxn],f[maxn];///f入度,g出度int dfn[maxn],low[maxn],v[maxn],s[maxn],b[maxn],h[maxn];int n,tot=0,cnt=0,ans=0,ans2,times,t;void init(){ tot=0; memset(h,0,sizeof(h));}void ins(int x,int y) ///tot 从1开始{ e[++tot].x=x; e[tot].y=y; e[tot].next=h[x]; h[x]=tot;}int max(int a,int b){ if(a>b) return a; return b;}int min(int a,int b){ if(a<b) return a; return b;}void Tarjan(int x){ int y,i; times++; t++; dfn[x]=low[x]=times; v[x]=1; s[t]=x; for (i=h[x]; i; i=e[i].next) { y=e[i].y; if (v[y]==0) { Tarjan(y); low[x]=min(low[x],low[y]); } if (v[y]==1) low[x]=min(low[x],dfn[y]); } if (dfn[x]==low[x]) { cnt++; do { y=s[t--]; b[y]=cnt;///属于哪个强连通分量 v[y]=2; // num[cnt]++; } while (y!=x); }}void solve(){ times=0; t=0; cnt=0;///连通分量个数 memset(dfn,0,sizeof(dfn)); //memset(num,0,sizeof(num)); memset(v,0,sizeof(v)); for(int i=1; i<=n; i++) if(!dfn[i]) Tarjan(i);}int main(){ int x,y; int p; while(scanf("%d%d",&n,&p)!=-1) { if(n==1) { cout<<0<<endl; continue; } init(); for(int i=0; i<p; i++) { scanf("%d%d",&x,&y); ins(x,y); } solve(); memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); for (int i=1; i<=tot; i++) if (b[e[i].x]!=b[e[i].y]) { f[b[e[i].x]]++; g[b[e[i].y]]++; } ans=0,ans2=0; for (int i=1; i<=cnt; i++)///强连通分量 { if (g[i]==0) ans++; if (f[i]==0) ans2++; } if(n<1||cnt==1)///只有一个强连通分量,其本身就是强连通图咯 { printf("0\n"); continue; } printf("%d\n",max(ans,ans2)); } return 0;}
0 0
- hdu3836
- hdu3836
- HDU3836 Tarjan缩点
- HDU3836(tarjan+缩点)
- HDU3836 强联通 裸题
- hdu3836 Equivalent Sets
- hdu3836 Equivalent Sets(缩点)
- hdu3836及Tarjon算法模板
- hdu3836 强联通水题
- hdu3836 Equivalent Sets【强连通】
- hdu3836 最强连通图,trajan算法...
- HDU3836--Equivalent Sets(强连通+缩点)
- HDU3836 Equivalent Sets 强联通分量 Tarjan
- hdu3836之强联通缩点
- HDU3836 Equivalent Sets :Tarjan缩点
- 强连通 Tarjan+Kosaraju (HDU1269+hdu3836)
- HDU3836(强联通分量+思维)
- 有向图的强连通分量 hdu3836
- Sublime Text 2/3 使用心得
- java 图片如何让白色变透明
- 两种排序(快排+冒泡)
- 设置Label圆角
- Java安装主要步骤及刚刚导入项目时可能出现的问题
- hdu3836
- Android禁止横竖屏和解决切换屏幕时重启Activity的方法
- TCP四次握手释放连接
- spring之事务管理2
- 当一个动画结束之后继续执行下一个动画
- CSS入门基础
- hdu 1561 (树形dp+依赖背包)
- 拿到当前窗口
- 如何完全退出Android程序 (2012-07-20 22:29:26)