题目大意:
曹操有N个岛,这些岛用M座桥连接起来,每座桥有士兵把守(也可能没有),
诸葛亮把所有炸弹都带走了,只留下一枚给周瑜(真狠)。
周瑜想让这N个岛不连通,但需要派出不小于守桥士兵数的人去炸桥,因为只有一枚炸弹,因此只够炸掉一座桥。
分析:
很明显的求代价最小的桥,当然这道题有几个特殊的地方:
1.图本来就不联通,输出0;
2.无解(不存在桥),输出-1;
3.没人把守,但你还是得派一个人炸桥,输出1;
4.一般情况,输出最小代价。
剩下的就是模板了,不过需要注意的一点是,这道题可能有重边,因此只是不能走回这条边,而不一定不能走回这个点。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define mem(a,p) memset(a,p,sizeof(a)) 5 const int N=1e3+7,M=2e6+7; 6 int read(){ 7 int ans=0,f=1;char c=getchar(); 8 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 9 while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();} 10 return ans*f; 11 } 12 int n,tot,m,first[N],num,low[N],dfn[N],mni,ss; 13 struct node{ 14 int ne,to,w; 15 void operator = (const node&p){ne=p.ne;to=p.to;w=p.w;} 16 }e[M]; 17 void ins(int u,int v,int c){e[++tot]=(node){first[u],v,c};first[u]=tot;} 18 void init(){ 19 tot=0;num=0;mni=999999999;ss=0; 20 mem(first,0);mem(dfn,0);mem(low,0); 21 } 22 void tarjan(int x,int fa){ 23 dfn[x]=low[x]=++num; 24 for(int i=first[x];i;i=e[i].ne){ 25 int to=e[i].to; 26 if(!dfn[to]){ 27 tarjan(to,x); 28 if(low[to]<low[x])low[x]=low[to]; 29 if(low[to]>dfn[x]){ 30 if(e[i].w<mni)mni=e[i].w;ss++; 31 } 32 } 33 else if(to!=fa&&dfn[to]<low[x])low[x]=dfn[to]; 34 } 35 } 36 int main(){ 37 n=read();m=read(); 38 while(n||m){ 39 init(); 40 for(int i=1,a,b,c;i<=m;i++){ 41 a=read();b=read();c=read(); 42 ins(a,b,c);ins(b,a,c); 43 } 44 int flag=0; 45 for(int i=1;i<=n;i++) 46 if(!dfn[i]){ 47 if(flag){flag=2;break;} 48 tarjan(i,0); 49 flag=1; 50 } 51 if(flag==2)printf("0 "); 52 else if(ss==0)printf("-1 "); 53 else if(mni==0)printf("1 "); 54 else printf("%d ",mni); 55 n=read();m=read(); 56 } 57 return 0; 58 }