题意:给你n个点,m条边,边有权值,问你最小的花费使图不连通;
解题思路:就是求边权最小的割边,但这道题有坑点:
1、有重边(桥的两个点有重边时,你去掉一条边并没什么d用);
2、当权值为0的时候,我们也需要放一个人(被这个坑死了0.0);
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #define maxn 1100 #define inf 0x3f3f3f3f using namespace std; struct Edge { int next; int to; int w; }edge[maxn*maxn*2]; int head[maxn*maxn]; int low[maxn*maxn]; int dfn[maxn*maxn]; int n,m; int flag; int minn; int cnt,step; int bridge; void init() { memset(head,-1,sizeof(head)); memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); cnt=0;step=0;bridge=0;flag=0;minn=inf; } void add(int u,int v,int w) { edge[cnt].next=head[u]; edge[cnt].to=v; edge[cnt].w=w; head[u]=cnt++; } void tarjan(int u,int fa) { dfn[u]=low[u]=++step; int num=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(fa==v&&num==0) { num++; continue; } // cout<<v<<endl; if(!dfn[v]) { tarjan(v,u); low[u]=min(low[u],low[v]); if(low[v]>dfn[u]) { bridge++; minn=min(minn,edge[i].w); } } else low[u]=min(low[u],dfn[v]); } } void solve() { int ans=0; for(int i=1;i<=n;i++) { if(!dfn[i]) { ans++; tarjan(i,i); } } if(ans>=2) { printf("0\n"); return; } if(bridge==0) printf("-1\n"); else { if(minn==0) printf("1\n"); else printf("%d\n",minn); } } int main() { int x,y,w; while(scanf("%d%d",&n,&m)!=EOF) { init(); if(n==0&&m==0) break; for(int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&w); add(x,y,w); add(y,x,w); } solve(); } return 0; }
原文地址:https://www.cnblogs.com/huangdao/p/9017436.html
时间: 2024-10-10 10:40:16