Caocao's Bridges(重边无向图求桥)

Caocao was defeated by Zhuge Liang and Zhou Yu in the battle of Chibi. But he wouldn't give up. Caocao's army still was not good at water battles, so he came up with another idea. He built many islands in the Changjiang river, and based on those islands, Caocao's army could easily attack Zhou Yu's troop. Caocao also built bridges connecting islands. If all islands were connected by bridges, Caocao's army could be deployed very conveniently among those islands. Zhou Yu couldn't stand with that, so he wanted to destroy some Caocao's bridges so one or more islands would be seperated from other islands. But Zhou Yu had only one bomb which was left by Zhuge Liang, so he could only destroy one bridge. Zhou Yu must send someone carrying the bomb to destroy the bridge. There might be guards on bridges. The soldier number of the bombing team couldn't be less than the guard number of a bridge, or the mission would fail. Please figure out as least how many soldiers Zhou Yu have to sent to complete the island seperating mission.
InputThere are no more than 12 test cases. 

In each test case: 

The first line contains two integers, N and M, meaning that there are N islands and M bridges. All the islands are numbered from 1 to N. ( 2 <= N <= 1000, 0 < M <= N  2

Next M lines describes M bridges. Each line contains three integers U,V and W, meaning that there is a bridge connecting island U and island V, and there are W guards on that bridge. ( U ≠ V and 0 <= W <= 10,000 ) 

The input ends with N = 0 and M = 0. OutputFor each test case, print the minimum soldier number Zhou Yu had to send to complete the mission. If Zhou Yu couldn't succeed any way, print -1 instead. Sample Input
3 3
1 2 7
2 3 4
3 1 4
3 2
1 2 7
2 3 4
0 0
Sample Output
-1
4

题意:现在有个(可重边)无向图,无向图的每条边上都有一定数目的守卫,你现在想派人去炸掉这个图的一条边,是的该图不连通。但是你只能炸1条边且如果该边守卫为x人,那么你至少要派x个人过去。所以现在问你最少需要派多少人出发?

思路:

本题的本质还是无向图求桥,且求得是守卫数目最少的那个桥。但是本题有3个点要注意:

 1.所给的图可能不连通,且不连通的时候不需要炸,输出0.
 2.当所要去炸的桥上的守卫数=0时,我们需要派的人数是1不是0.
3.任意两个节点u与v之间可能存在多条边。

对于上面的1与2点,我们在原始tarjan()函数运行完后加一些判断就能解决.对于3的话,如果有重边的话那么就一定不是桥,那么只需要给一个特别一点值,在dfs里面更新的时候判断如果是这个特别的值就可以跳过了

代码:

#include
#include
#include
using namespace std;
const int maxn=1500+10;
const int INF = 100000000;
int ans;
int n,m;
int dfs_clock;//时钟,每访问一个节点增1
vector G[maxn];//G[i]表示i节点邻接的所有节点
int pre[maxn];//pre[i]表示i节点被第一次访问到的时间戳,若pre[i]==0表示i还未被访问
int low[maxn];//low[i]表示i节点及其后代能通过反向边连回的最早的祖先的pre值
bool iscut[maxn];//标记i节点是不是一个割点
int adj[maxn][maxn];
int pointnum;
//求出以u为根节点(u在DFS树中的父节点是fa)的树的所有割顶和桥
//初始调用为dfs(root,-1);
int dfs(int u,int fa)
{
    int lowu=pre[u]=++dfs_clock;
    int child=0;    //子节点数目
    for(int i=0; i=pre[u])
            {
                iscut[u]=true;      //u点是割顶
                if(lowv>pre[u] && adj[u][v]!=-2)   //(u,v)边是桥
                    ans = min(ans,adj[u][v]);
            }
        }
        else if(pre[v]

地址:点击打开链接




 

你可能感兴趣的:(图论算法)