割点与桥

定义

割点:删掉该点后,原连通图分裂为多个子图;

桥:删掉该边后,原连通图分裂为多个子图;

求割点:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=150000+10;
int dfn[maxn],low[maxn];
bool iscut[maxn];
vector<int>pic[maxn];
int dfs_clock=0;
void tarjan(int x,int fa)
{
	int child=0;
	dfn[x]=low[x]=++dfs_clock;
	for (int i=0;i<pic[x].size();i++)
	{
		int y=pic[x][i];
		if (y==fa) continue;
		if (!dfn[y])
		{
			child++;
			tarjan(y,x);
			low[x]=min(low[x],low[y]);
			if (low[y]>=dfn[x]) iscut[x]=true; 
		}
		else low[x]=min(low[x],dfn[y]);
	}
	if (fa==-1&&child<=1) iscut[x]=false;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		pic[x].push_back(y);
		pic[y].push_back(x);
	}
	memset(dfn,0,sizeof(dfn));
	memset(iscut,0,sizeof(iscut));
	for (int i=1;i<=n;i++)
	if (!dfn[i]) tarjan(i,-1);
	int cnt=0;
	for (int i=1;i<=n;i++) if (iscut[i]) cnt++;
	printf("%d\n",cnt);
	return 0;
}

  求桥:

#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=100;
vector<int>pic[maxn];
int dfn[maxn],low[maxn];
int dfs_clock=0;
void tarjan(int x,int fa)
{
	dfn[x]=low[x]=++dfs_clock;
	for (int i=0;i<pic[x].size();i++)
	{
		int y=pic[x][i];
		if (y==fa) continue;
		if (!dfn[y])
		{
			tarjan(y,x);
			low[x]=min(low[x],low[y]);
		}
		else low[x]=min(low[x],dfn[y]);
	}
	if (dfn[x]==low[x]&&fa!=-1) printf("Find Bridge:%d %d\n",fa,x);
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		pic[x].push_back(y);
		pic[y].push_back(x);
	}
	memset(dfn,0,sizeof(dfn));
	for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i,-1);
	return 0;
}

 

posted @ 2017-07-03 21:54  PaperCloud  阅读(160)  评论(0编辑  收藏  举报