传送门
题意:略。
思路:如果所有点不在1个图中,输出0,因为不需要去炸了。
否则,求出最小权的桥,如果权值为0,则输出1,这里要注意,因为总要有人去炸;不过最小权大于0,直接输出。如果没桥,输出-1。
#include<iostream> #include<cstdio> #include<cstring> #include<stack> using namespace std; stack<int>st; int n,m; int fst[1005],next[1000005],node[1000005],w[1000005],en; int d[1005]; int scnum; bool ve[1000005]; int dnum,ans; int dfn[1005],low[1005],num; bool inst[1005]; void init() { scnum=0; en=0; dnum=0; num=0; ans=100000; memset(fst,-1,sizeof(fst)); memset(ve,0,sizeof(ve)); memset(dfn,0,sizeof(dfn)); memset(inst,0,sizeof(inst)); } void add(int u,int v,int c) { next[en]=fst[u]; fst[u]=en; node[en]=v; w[en]=c; en++; } void tarjan(int u) { dfn[u]=low[u]=++num; st.push(u); inst[u]=1; for(int i=fst[u];i!=-1;i=next[i]) { if(ve[i])continue; int v=node[i]; ve[i]=ve[i^1]=1; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); if(low[v]>dfn[u]) { ans=min(ans,w[i]); } } else if(inst[v]) { low[u]=min(dfn[v],low[u]); } } if(dfn[u]==low[u]) { scnum++; int v; do { v=st.top(); st.pop(); inst[v]=0; d[v]=scnum; }while(u!=v); } } int main() { int u,v,c; while(scanf("%d%d",&n,&m)) { if(m==0&&n==0)break; init(); for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&c); add(u,v,c); add(v,u,c); } for(int i=1;i<=n;i++) { if(!dfn[i]) { tarjan(i); dnum++; } } if(dnum>1)cout<<0<<endl; else if(ans==0)cout<<1<<endl; else if(ans==100000)cout<<-1<<endl; else cout<<ans<<endl; } return 0; }