HDU 4738 --Caocao's Bridges 【无向图边双联通 && 求权值最小的桥 && 模板】

Caocao‘s Bridges

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 2641    Accepted Submission(s): 855

Problem Description

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.

Input

There 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 <= N2 )

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.

Output

For 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

题意:有n座岛和m条桥,每条桥上有w个兵守着,现在要派不少于守桥的士兵数的人去炸桥,只能炸一条桥,使得这n座岛不连通,求最少要派多少人去。

分析:只需要用Tarjan算法求出图中权值最小的那条桥就行了。

注意:

一:如果图不连通,不用派人去炸桥,直接输出0

二:可能会有重边

三:如果桥上没有士兵守着,那至少要派一个人去炸桥。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define maxn 1010
#define maxm 1000100
#define INF 0x3f3f3f3f
using namespace std;
int n, m;
int low[maxn];
int dfn[maxn];
int head[maxn], cnt;
int dfs_clock;
int mark;//判断图是否连通

struct node{
    int u, v, w, cnt, next;
};

node edge[maxm];

void init(){
    cnt = 0;
    memset(head, -1, sizeof(head));
}

void add(int u, int v, int w){
    edge[cnt] = {u, v, w, 0, head[u]};
    head[u] = cnt++;
    edge[cnt] = {v, u, w, 0, head[v]};
    head[v] = cnt++;
}

void input(){
    while(m--){
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        add(u, v, w);
    }
}

void tarjin(int u, int fa){
    low[u] = dfn[u] = ++dfs_clock;
    int flag = 1;
    for(int i = head[u]; i != -1; i = edge[i].next){
        int v = edge[i].v;
        if(flag && v == fa){//去重边,重边不可能是桥
            flag = 0;
            continue;
        }
        if(!dfn[v]){
            tarjin(v, u);
            low[u] = min(low[u], low[v]);
            if(dfn[u] < low[v])//是桥
                edge[i].cnt = edge[i ^ 1].cnt = 1;
        }
        else
            low[u] = min(low[u], dfn[v]);
    }
}

void find(){
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0, sizeof(low));
    dfs_clock = 0;
    tarjin(1, 1);
    mark = 1;
    for(int i = 1; i <= n; ++i){
        if(!dfn[i]){
            mark = 0;
            return ;
        }
    }
}

void solve(){
    if(!mark)
        printf("0\n");
    else{
        int ans = INF;
        for(int i = 0; i < cnt; ++i){
            if(edge[i].cnt)
                ans = min(ans, edge[i].w);
        }
        if(ans == INF)
            ans = -1;
        if(ans == 0)
            ans = 1;
        printf("%d\n", ans);
    }
}

int main (){
    while(scanf("%d%d", &n, &m), n || m){
        init();
        input();
        find();
        solve();
    }
    return 0;
}

另一种去重边的方式,对这一题来说处理时间比较慢

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define maxn 1010
#define maxm 1000100
#define INF 0x3f3f3f3f
using namespace std;
int n, m;
int low[maxn];
int dfn[maxn];
int head[maxn], cnt;
int dfs_clock;
int mark;//判断图是否连通

struct node{
    int u, v, w, cnt, next, again;//again标记是不是有重边
};

node edge[maxm];

void init(){
    cnt = 0;
    memset(head, -1, sizeof(head));
}

void add(int u, int v, int w){
    int i;
    //标记重边
    for(i = head[u]; i != -1; i = edge[i].next){
        if(edge[i].v == v){
            break;
        }
    }
    if(i != -1)
        edge[i].again = 1;
    else{
        edge[cnt] = {u, v, w, 0, head[u], 0};
        head[u] = cnt++;
    }
}

void input(){
    while(m--){
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        add(u, v, w);
        add(v, u, w);
    }
}

void tarjin(int u, int fa){
    low[u] = dfn[u] = ++dfs_clock;
    for(int i = head[u]; i != -1; i = edge[i].next){
        int v = edge[i].v;
        if(v == fa) continue;
        if(!dfn[v]){
            tarjin(v, u);
            low[u] = min(low[u], low[v]);
            if(dfn[u] < low[v] && edge[i].again == 0)//是桥
                edge[i].cnt = edge[i ^ 1].cnt = 1;
        }
        else
            low[u] = min(low[u], dfn[v]);
    }
}

void find(){
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0, sizeof(low));
    dfs_clock = 0;
    tarjin(1, -1);
    mark = 1;
    for(int i = 1; i <= n; ++i){
        if(!dfn[i]){
            mark = 0;
            return ;
        }
    }
}

void solve(){
    if(!mark)
        printf("0\n");
    else{
        int ans = INF;
        for(int i = 0; i < cnt; ++i){
            if(edge[i].cnt)
                ans = min(ans, edge[i].w);
        }
        if(ans == INF)
            ans = -1;
        if(ans == 0)
            ans = 1;
        printf("%d\n", ans);
    }
}

int main (){
    while(scanf("%d%d", &n, &m), n || m){
        init();
        input();
        find();
        solve();
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU 4738 --Caocao's Bridges 【无向图边双联通 && 求权值最小的桥 && 模板】

时间: 2024-08-01 10:45:28

HDU 4738 --Caocao's Bridges 【无向图边双联通 && 求权值最小的桥 && 模板】的相关文章

hdu Caocao&#39;s Bridges(无向图边双连通分量,找出权值最小的桥)

1 /* 2 题意:给出一个无向图,去掉一条权值最小边,使这个无向图不再连同! 3 4 tm太坑了... 5 1,如果这个无向图开始就是一个非连通图,直接输出0 6 2,重边(两个节点存在多条边, 权值不一样) 7 3,如果找到了桥的最小权值为0,也就是桥上的士兵数为0,那么还是要最少派一个 8 士兵过去炸掉桥! 9 10 思路:假设每两个节点最多只有一条边进行相连! 11 进行tarjan算法,如果该算法调用了超过2次,说明这个原图就是不连通的! 12 否则在tarjan算法中将桥存起来!然后

HDU 4738 Caocao&#39;s Bridges(双联通分量+并查集)

大意:有n座岛和m条桥,每条桥上有w个兵守着,现在要派不少于守桥的士兵数的人去炸桥,只能炸一条桥,使得这n座岛不连通,求最少要派多少人去. 思路:我们就是要缩点后直接求桥上人的最少数量.(PS:1.注意图如果不联通直接输出0.2.如果图中的桥上人为0,个那么要让一个人去.3.重边的问题.这里可以忽略) #include<map> #include<queue> #include<cmath> #include<cstdio> #include<stac

HDU 4738 Caocao&#39;s Bridges tarjan求桥

Caocao's Bridges Problem Description 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 Chan

HDU 4738——Caocao&#39;s Bridges——————【求割边/桥的最小权值】

Caocao's Bridges Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4738 Description Caocao was defeated by Zhuge Liang and Zhou Yu in the battle of Chibi. But he wouldn't give up. Caocao's army st

HDU 4738 Caocao&#39;s Bridges ——(找桥,求联通块)

题意:给你一个无向图,给你一个炸弹去炸掉一条边,使得整个图不再联通,你需要派人去安置炸弹,且派去的人至少要比这条边上的人多.问至少要派去多少个,如果没法完成,就输出-1. 分析:如果这个图是已经是多个联通块了,那么一个人都不用去,如果不是,那么只要找出这个无向图上的桥并且哨兵数量最少的那座把它炸了就行(输出这条边上的哨兵数量即可).直接tarjan就可以写. 注意点:1.可能有重边,所以用手写邻接表的方式存图:2.如果一座桥上没有哨兵,那么你也得至少派去一个人去安置炸弹(因为炸弹不会自己飞过去啊

HDU 4738 Caocao&#39;s Bridges(割边)

乍一看一个模板题,仔细一看还是模板题,但是三个坑.1,不是连通图,放0个.2 守卫为0,放1个. 3注意重边. #include<iostream> #include<cstdio> #include<vector> #include<queue> #include<algorithm> #include<stack> #include<cstring> using namespace std; #define maxn

HDU 4738 Caocao&#39;s Bridges(找割边)

HDU 4738 Caocao's Bridges 题目链接 注意几个坑,可能重边,至少要派一个人去炸,没有连通的时候就不用炸了 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 1005; const int INF = 0x3f3f3f3f; int pre[N], low[N

hdu 4738 Caocao&#39;s Bridges tarjan

Caocao's Bridges Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4738 Description 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

HDU 4738 Caocao&#39;s Bridges(求价值最小的桥)

Problem Description 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