hdu 4738 Caocao's Bridges 有重边求割边模板

题意:找到一条最小割边,输出其权值。

有几点需要注意:

1.如果割边权为0了,则至少需要1人去炸毁桥。

2.如果一开始就没连通,就不需要人,输出0

有重边求割边模板

//思路:会出现重边 , 统计每条边的边数,注意规定边的两端大小,若是重边,判断时直接放弃 
//有重边 求割边模板 
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<stack>
#include<vector>
#include<map>
#include<string>
#include<iostream>
using namespace std;
const int maxn = 2*1e4+10;
int low[maxn],dfn[maxn];
map<int,int> mp;
int time;
struct edge
{
	int from,to,w;
}e[1000000+10];
vector<int> g[maxn];
void tarjan(int u,int fa)
{
	dfn[u]=low[u]=++time;
	for(int i=0;i<g[u].size();i++)
	{
		int v=g[u][i];
		if(!dfn[v])
		{
			tarjan(v,u);
			low[u]=min(low[v],low[u]);
		}
		else if(v!=fa)
			low[u]=min(low[u],dfn[v]);
	}
}
void init(int cnt)
{
	memset(dfn,0,sizeof(dfn));
	for(int i=1;i<=cnt;i++)
		g[i].clear();
	time=0;
	mp.clear();
}
int main()
{
	int n,m;
	while(~scanf("%d%d",&n,&m)&&(n+m))
	{
		int cnt=0;
		init(n);
		for(int i=0;i<m;i++)
		{
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);	//方便标号统计重边 
			if(u>v)swap(u,v);
			e[i].from=u,e[i].to=v,e[i].w=w;
			g[u].push_back(v);
			g[v].push_back(u);
			mp[u*1000000+v]++;
		}
		tarjan(1,-1);
		int flag=0;
		for(int i=1;i<=n;i++)
		if(!dfn[i])flag=1;
		if(flag)
		{
			printf("0\n");		//不联通,割边数为0 
		}
		else
		{
			int mi=1<<30;
			for(int i=0;i<m;i++)
			{
				int u=e[i].from,v=e[i].to;
				if((low[u]>dfn[v]||low[v]>dfn[u])&&mp[u*1000000+v]==1)//排除重边  是割边 
				{
					if(mi>e[i].w)mi=e[i].w;
				}
			}
			if(mi==0)
			printf("1\n");
			else if(mi!=1<<30)
			printf("%d\n",mi);
			else
			printf("-1\n");
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值