【POJ3352】Road Construction tarjan求边-双连通分量,裸题模板题

转载请注明出处:http://blog.csdn.net/vmurder/article/details/42671851

其实我就是觉得原创的访问量比未授权盗版多有点不爽233。。。

裸题只给模板。

tarjan可以实现。

太水不发题解。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1010
#define M 2020
using namespace std;
struct KSD
{
	int v,next;
}e[M];
int head[N],cnt;
inline void add(int u,int v)
{
	e[++cnt].v=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int dfn[N],low[N],n,m;
int id[N],group,d[N];
int ans,edges; // 边-双个数、 桥个数
int stk[N],top;

void tarjan(int x,int p) // 边双连通分量,即无桥。
{
	int i,v,temp;
	dfn[x]=low[x]=++cnt;
	stk[++top]=x;
	for(i=head[x];i;i=e[i].next)
	{
		v=e[i].v;
		if(v==p)continue;
		if(!dfn[v])
		{
			tarjan(v,x);
			low[x]=min(low[x],low[v]);
		}
		else low[x]=min(low[x],dfn[v]);
//		if(dfn[x]<low[v])edges++; // 桥的数目
	}
	if(dfn[x]==low[x])
	{
		group++;
		do{
			temp=stk[top--];
			id[temp]=group;
		}while(temp!=x);
	}
	return ;
}

int main()
{
//	freopen("test.in","r",stdin);
	int i,j,k;
	int a,b,c;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(head,0,sizeof(head));
		memset(dfn,0,sizeof(dfn));
		memset(d,0,sizeof(d));
		cnt=group=ans=0;

		for(i=1;i<=m;i++)
		{
			scanf("%d%d",&a,&b);
			add(a,b),add(b,a);
		}
		cnt=0;
		for(i=1;i<=n;i++)if(!dfn[i])tarjan(i,0);
		for(j=1;j<=n;j++)
			for(i=head[j];i;i=e[i].next)
				if(id[j]!=id[e[i].v])d[id[e[i].v]]++;
		for(i=1;i<=n;i++)if(d[i]==1)ans++;

		printf("%d\n",ans+1>>1);
	}

	return 0;
}
时间: 2024-10-10 07:43:52

【POJ3352】Road Construction tarjan求边-双连通分量,裸题模板题的相关文章

poj3352 road construction tarjan求双连通分量

填坑--链接:http://poj.org/problem?id=3352 题意:求出图中再加上几条边会全部边双连通. 思路大概就是求出图中所有的双连通分量,然后像$SCC$一样缩点,缩完后每两个双连通分量再连边即可. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn

【POJ1523】SPF tarjan求点-双连通分量 裸题模板题

转载请注明出处:http://blog.csdn.net/vmurder/article/details/42671865 其实我就是觉得原创的访问量比未授权盗版多有点不爽233... 题意:求哪些点是割点,割掉以后能把图分成几块. 太水不欲发题解. tarjan就好,不懂看代码. 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define

POJ3352 Road Construction Tarjan+边双连通

题目链接:http://poj.org/problem?id=3352 题目要求求出无向图中最少需要多少边能够使得该图边双连通. 在图G中,如果任意两个点之间有两条边不重复的路径,称为“边双连通”,去掉任何一条边都是其他边仍然是连通的,也就是说边双连通图中没有割边. 算法设计是:运用tarjan+缩点.对于每一个边双连通分量,我们都可以把它视作一个点,因为low值相同的点处在同一个边双连通分量中,可以简单地思考一下,(u,v)之间有两条可达的路径,dfs一定可以从一条路开始搜索并且从另一条路回去

bzoj1123 BLO tarjan求点双连通分量

填坑--链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1123 题意:问切断第i个点之后多少对点不再联通. 就是个求割点同时计算出双连通分量大小嘛-- 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=10000

Tarjan求点双连通分量

概述 在一个无向图中,若任意两点间至少存在两条"点不重复"的路径,则说这个图是点双连通的(简称双连通,biconnected) 在一个无向图中,点双连通的极大子图称为点双连通分量(简称双连通分量,Biconnected Component,BCC) 性质 任意两点间至少存在两条点不重复的路径等价于图中删去任意一个点都不会改变图的连通性,即BCC中无割点 若BCC间有公共点,则公共点为原图的割点 无向连通图中割点一定属于至少两个BCC,非割点只属于一个BCC 算法 在Tarjan过程中维

poj 3352Road Construction(无向双连通分量的分解)

1 /* 2 题意:给定一个连通的无向图G,至少要添加几条边,才能使其变为强连通图(指的是边强联通). 3 思路:利用tarjan算法找出所有的双联通分量!然后根据low[]值的不同将双联通分量 4 进行缩点,最后图形会变成一棵树!也就是添加至少多少条边使一棵树变成强联通图! 5 6 知识点:若要使得任意一棵树,在增加若干条边后,变成一个双连通图,那么 7 至少增加的边数 =( 这棵树总度数为1的结点数 + 1 )/ 2 8 9 */ 10 #include<iostream> 11 #inc

poj 3352 求 边-双连通分量

[题意] 给出一张无向连通图,求至少连几条边可以变成边双连通图 [思路]求出边-双连通分量,缩点就成了一棵树,求这棵树里的出度为1 的点num  结果是(num-1)/2; 1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<stack> 5 #include<vector> 6 using namespace std; 7 int pre[1002],

poj3352 Road Construction &amp; poj3177 Redundant Paths (边双连通分量)题解

题意:有n个点,m条路,问你最少加几条边,让整个图变成边双连通分量. 思路:缩点后变成一颗树,最少加边 = (度为1的点 + 1)/ 2.3177有重边,如果出现重边,用并查集合并两个端点所在的缩点后的点. 代码: /*3352*/ #include<set> #include<map> #include<stack> #include<cmath> #include<queue> #include<vector> #include&

【连通图|边双连通+缩点】POJ-3352 Road Construction

Road Construction Time Limit: 2000MS Memory Limit: 65536K Description It's almost summer time, and that means that it's almost summer construction time! This year, the good people who are in charge of the roads on the tropical island paradise of Remo