hdu 4738 Caocao's Bridges【求割橋】
阿新 • • 發佈:2018-12-07
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=4738
題目大意:有N個島嶼和M座橋,每座橋都有士兵守衛,現在想炸燬一座橋使所有的島嶼不能強連通,炸橋隊的人數不能比守衛橋的人數少,求炸橋隊的最小人數;
思路:意思就是讓求出邊權最下的那個割橋,這個是求割橋的模板 模板連結;
這個題需要注意:如果求出的割橋邊權是0的話,那麼答案應該是1,因為需要一個人去炸橋;
#include<cstring> #include<string> #include<cstdio> #include<stdlib.h> #include<iostream> #include<algorithm> #include<math.h> #include<map> #include<vector> #include<stack> #define inf 0x3f3f3f3f #include<queue> #include<set> using namespace std; typedef long long ll; const int N=5e3+5; const int M=5e6+5; struct node { int v,w,ne; }edge[M]; int head[N],low[N],dfn[N]; int cut,top,e,ans; int m,n; void init() { memset(head,-1,sizeof(head)); e=0; } void add(int a,int b,int c) { edge[e].v=b; edge[e].w=c; edge[e].ne=head[a]; head[a]=e++; } void tarjan(int now,int pre) { low[now]=dfn[now]=++top; bool flag=1; for(int i=head[now];i!=-1;i=edge[i].ne) { int v=edge[i].v; if(v==pre&&flag)//判斷重邊 { flag=0; continue; } if(!dfn[v]) { tarjan(v,now); low[now]=min(low[now],low[v]); if(dfn[now]<low[v]) ans=min(edge[i].w,ans); } else low[now]=min(low[now],dfn[v]); } } void solve() { memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); top=0; cut=0; ans=inf; for(int i=1;i<=n;i++) { if(!dfn[i]) { tarjan(i,-1); cut++; } } if(cut>1) ans=0;//如果原圖就不是連通,那麼ans=0; else if(ans==inf) ans=-1; else if(ans==0) ans=1;//如果邊權是0,那麼ans=1; printf("%d\n",ans); } int main() { while(~scanf("%d %d",&n,&m)) { if(!n&&!m) break; int a,b,c; init(); for(int i=0;i<m;i++) { scanf("%d %d %d",&a,&b,&c); add(a,b,c); add(b,a,c); } solve(); } return 0; }