hdoj3836Equivalent Sets【scc +缩点】

原创 2015年11月19日 21:08:16



Equivalent Sets

Time Limit: 12000/4000 MS (Java/Others)    Memory Limit: 104857/104857 K (Java/Others)
Total Submission(s): 3619    Accepted Submission(s): 1262


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.
 

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.
 

Output
For each case, output a single integer: the minimum steps needed.
 

Sample Input
4 0 3 2 1 2 1 3
 

Sample Output
4 2
Hint
Case 2: First prove set 2 is a subset of set 1 and then prove set 3 is a subset of set 1.
 

Source
 


题意:计算需要加多少边才能构成一个强连通图注意给的图本身就是一个强连通图的情况

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=100010;
int dfs_clock,scc_cnt;
int head[maxn];
int sccno[maxn];
int low[maxn],dfn[maxn];
bool instack[maxn];
int in[maxn],out[maxn];
stack<int>S;
vector<int>scc[maxn];
vector<int>G[maxn];
struct Node{
	int from,to,next;
}A[maxn];
int MAX(int a,int b){
	return a>b?a:b;
}
int MIN(int a,int b){
	return a<b?a:b;
}
void init(){
	dfs_clock=scc_cnt=0;
	memset(head,-1,sizeof(head));
	memset(sccno,0,sizeof(sccno));
	memset(instack,false,sizeof(instack));
	memset(in,0,sizeof(in));
	memset(out,0,sizeof(out));
	memset(low,0,sizeof(low));
	memset(dfn,0,sizeof(dfn));
}
void tarjan(int u,int pre){
	int v;
	dfn[u]=low[u]=++dfs_clock;
	S.push(u);instack[u]=true;
	for(int k=head[u];k!=-1;k=A[k].next){
		v=A[k].to;
		if(!dfn[v]){
			tarjan(v,u);
			low[u]=MIN(low[u],low[v]);
		}
		else if(instack[v]){
			low[u]=MIN(low[u],dfn[v]);
		}
	}
	if(low[u]==dfn[u]){
		scc_cnt++;scc[scc_cnt].clear();
		G[scc_cnt].clear();
		while(1){
			v=S.top();S.pop();
			instack[v]=false;
			scc[scc_cnt].push_back(v);
			sccno[v]=scc_cnt;
			if(u==v)break;
		}
	}
}
void suodian(int m){
	for(int i=0;i<m;++i){
		int u=sccno[A[i].from];
		int v=sccno[A[i].to];
		if(u!=v){
			G[u].push_back(v);
			in[v]++;out[u]++;
		}
	}
}
int main()
{
	int i,j,k,n,m;
	while(scanf("%d%d",&n,&m)!=EOF){
		init();
		for(i=0;i<m;++i){
			scanf("%d%d",&A[i].from,&A[i].to);
			A[i].next=head[A[i].from];
			head[A[i].from]=i;
		}
		for(i=1;i<=n;++i){
			if(!dfn[i]){
				tarjan(i,-1);
			}
		}
		if(scc_cnt==1){
			printf("%d\n",0);
			continue;
		}
		suodian(m);
		int ans1=0,ans2=0;
		for(i=1;i<=scc_cnt;++i){
			if(in[i]==0)ans1++;
			if(out[i]==0)ans2++;
		}
		printf("%d\n",MAX(ans1,ans2));
	}
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

tarjan模板(缩点,求有向图强连通分量)

整理出了这个tarjan模板,具体数组的功能代码都有注释。 const int N=100010; struct data { int to,next; } tu[N*2]; int head...
  • martinue
  • martinue
  • 2016年05月04日 15:53
  • 1574

scc缩点

缩点
  • mirror58229
  • mirror58229
  • 2017年09月14日 17:31
  • 98

hdoj 3836 Equivalent Sets 【tarjan 求SCC + 缩点】

 Equivalent Sets Time Limit: 12000/4000 MS (Java/Others)    Memory Limit: 104857/104857 K (Java/...
  • chenzhenyu123456
  • chenzhenyu123456
  • 2015年07月18日 21:40
  • 293

缩点

关于缩点 以前做某些图论题,常听校队的师兄说要“缩点”。但是什么是缩点,缩的是什么点,说的人很清楚,听的人却一头雾水。经过一番努力,本人终于明白了什么是“缩点”,分享一下个人的见解,若有不正确万望指...
  • mnlghttr
  • mnlghttr
  • 2013年09月19日 08:51
  • 1143

HDU3836--Equivalent Sets(强连通+缩点)

题目就是告诉你有m条边是从u通向v的,问你至少添加多少条边之后,能形成一个强连通。模版题。 #include #include #include #include #include #in...
  • u011639302
  • u011639302
  • 2014年01月23日 09:01
  • 661

消息扩散(Tarjan算法缩点处理)

P2002 消息扩散 题目概述 给定一张有向图,不保证无自环与重边,信息从某几个节点出发,沿单向路传播,现在给出n个节点及其之间的道路,问至少需要在几个节点发布信息才能让这所有节点都得到信息。 ...
  • Stockholm_Sun
  • Stockholm_Sun
  • 2017年08月11日 10:33
  • 216

poj 1236 Network (SCC缩点)

题目大意:N(2 考虑问题1:对于每个强连通分量至少需发放1个,再看其与其他强连通分量,如果强连通分量A与B,A->B可以传输,则只需在A发放软件。于是,求出强连通分量并进行缩点后,统计一下入度为0的...
  • u014679804
  • u014679804
  • 2015年06月27日 10:49
  • 319

hdu3836 Equivalent Sets(缩点)

知道了一些集合的包含关系,问至少还要知道多少个包含关系才能证明这些集合是相互等价的。相当于在图中加入一些边,使得原图任意两个点互达即强连通, #include #include #include...
  • hill_555
  • hill_555
  • 2013年07月31日 19:38
  • 284

poj 3352 Road Construction(点双连通分量缩点+缩点树变为双连通分量)

题目链接: 点击打开链接 题目大意: 给出一张图,问最少加多少条边,将他变成边双连通图 题目分析: 首先进行点双连通图缩点,(点双连通图一定是边双连通图),然后得到一棵树,对于一棵树,我...
  • qq_24451605
  • qq_24451605
  • 2015年07月15日 15:43
  • 801

POJ 2186【Tarjan算法(模板_缩点)】

//在一张有向无环图G,图G会包含很多环(环里面的点是等价的), //当然可以把环缩成一个点(利用tarjan缩点), //形成一棵树,题目要求是求除他以外的点都指向他,也就是只有一个叶子。 //因为...
  • KEYboarderQQ
  • KEYboarderQQ
  • 2016年05月15日 10:13
  • 891
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdoj3836Equivalent Sets【scc +缩点】
举报原因:
原因补充:

(最多只允许输入30个字)