题意:
曹操在赤壁之战中被诸葛亮和周瑜打败。但他不会放弃。曹操的军队还是不擅长打水仗,所以他想出了另一个主意。他在长江上建造了许多岛屿,在这些岛屿的基础上,曹操的军队可以轻易地攻击周瑜的军队。曹操还修建了连接岛屿的桥梁。如果所有的岛屿都用桥连接起来,曹操的军队就可以很方便地部署在这些岛屿之间。周瑜无法忍受,他想毁掉曹操的一些桥梁,把一个或多个岛屿与其他岛屿分开。周瑜身上只有一颗炸弹,是诸葛亮留下的,所以他只能毁掉一座桥。周瑜必须派人带着炸弹去炸毁那座桥。桥上可能有警卫。轰炸队的士兵人数不能少于一座桥的守卫人数,否则任务就会失败。请至少计算出周瑜要派多少士兵去完成离岛任务。
题解+代码:
1 //题解: 2 //这道题。。。。。。T_T 3 //这道题要先判断有没有桥,没有桥的话就直接输出-1 4 //如果有桥的话还要注意如果有一座桥上没有警卫,但是我们还是要派一人去炸桥 5 //所以要有两个特判,卧槽! 6 #include<stdio.h> 7 #include<string.h> 8 #include<iostream> 9 #include<algorithm> 10 #include<queue> 11 #include<map> 12 #include<vector> 13 using namespace std; 14 const int maxn = 1005; 15 const int INF=0x3f3f3f3f; 16 struct node { 17 int v, next,w; 18 }e[maxn*maxn*2+10]; 19 int head[maxn], cnt; 20 bool iscut[maxn]; 21 int dfn[maxn], low[maxn]; 22 int num,n,m,minn; 23 inline void add_edge(int xx, int yy,int zz) { 24 e[++cnt].next = head[xx]; 25 e[cnt].w=zz; 26 e[cnt].v = yy; 27 head[xx] = cnt; 28 } 29 30 inline void tarjan(int x, int in_edge) { 31 dfn[x] = low[x] = ++num; 32 for(int i = head[x]; i; i = e[i].next) { 33 int to = e[i].v; 34 if(!dfn[to]) { 35 tarjan(to, i); 36 low[x] = min(low[x], low[to]); 37 if(low[to] > dfn[x]) 38 iscut[i] = iscut[i ^ 1] = true,minn=min(minn,e[i].w); 39 } 40 else if(i != (in_edge ^ 1)) 41 low[x] = min(low[x], dfn[to]); 42 } 43 } 44 int main() 45 { 46 while(~scanf("%d%d",&n,&m) && (n+m)) 47 { 48 49 cnt=1; 50 num=0; 51 memset(iscut,0,sizeof(iscut)); 52 memset(head,0,sizeof(head)); 53 memset(dfn,0,sizeof(dfn)); 54 memset(low,0,sizeof(low)); 55 while(m--) 56 { 57 int x,y,z; 58 scanf("%d%d%d",&x,&y,&z); 59 add_edge(x,y,z); 60 add_edge(y,x,z); 61 } 62 int flag=0; 63 minn=INF; 64 for(int i=1;i<=n;++i) 65 { 66 if(!dfn[i]) 67 { 68 tarjan(i,0); 69 flag++; 70 } 71 } 72 if(flag>1) 73 { 74 printf("0 "); 75 } 76 else 77 { 78 if(minn==INF) printf("-1 "); 79 else if(minn==0) printf("1 "); 80 else printf("%d ",minn); 81 } 82 } 83 return 0; 84 }