hdu-4738(tarjan割邊)
阿新 • • 發佈:2018-05-10
CP bridge Go names iostream OS urn truct algo
題意:給你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; }
hdu-4738(tarjan割邊)