[hdu4738] 无向图找桥

最近的考试暴露了我图论知识一片空白的事实…
所以现在还是开始填坑吧…

这道题是无向图找桥的模板题

然后有几个需要注意的地方
1.有重边,用邻接矩阵判断边权设为无穷大即可
2.如果桥上没有人也要派一个人带炸弹过去

大概就这些 剩下的用 t a r j a n 就好了

题目链接

Codes

#include<bits/stdc++.h>
#define For(i, a, b) for(register int i = a; i <= b; ++ i)
#define go(x, i) for(register int i = head[x]; i; i = nxt[i])

using namespace std;

const int maxn = 1e3 + 5;
int to[maxn * maxn], head[maxn], nxt[maxn * maxn], v[maxn * maxn], e;
int mp[maxn][maxn];
int cnt, n, m, dfn[maxn], low[maxn], ans;

void add(int x, int y, int z, bool k = 1) {
    to[++ e] = y;
    nxt[e] = head[x];
    head[x] = e;
    v[e] = z;
    if(k) add(y, x, z, 0);
}

void dfs(int x, int from) {
    dfn[x] = low[x] = ++ cnt;
    go(x, i) 
        if(to[i] != from) {
            if(!dfn[to[i]]) {
                dfs(to[i], x);
                low[x] = min(low[x], low[to[i]]);
                if(low[to[i]] > dfn[x]) 
                    ans = min(ans, v[i]);
            }
            else
                low[x] = min(low[x], dfn[to[i]]);
        }
}

void File() {
    freopen("4738.in", "r", stdin);
    freopen("4738.out", "w", stdout);
}

void Init() {
    int x, y, z;
    scanf("%d%d", &n, &m);
    cnt = e = 0, ans = INT_MAX;
    For(i, 1, n) {
        head[i] = dfn[i] = low[i] = 0;
        For(j, 1, n) 
            mp[i][j] = -1;
    }
    if(n + m == 0) exit(0);
    For(i, 1, m) {
        scanf("%d%d%d", &x, &y, &z);
        if(mp[x][y] == -1) mp[x][y] = mp[y][x] = z;
        else mp[x][y] = mp[y][x] = INT_MAX;
    }   
    For(i, 1, n) 
        For(j, 1, n)
            if(mp[i][j] != -1)
                add(i, j, mp[i][j]);
}

void Solve() {
    dfs(1, 0);
    For(i, 1, n) 
        if(!dfn[i]) 
            return void(printf("%d\n", 0));
    if(ans == INT_MAX) printf("-1\n");
    else if(ans == 0) printf("1\n");
    else printf("%d\n", ans);
}

int main() {
    File();
    while(true) {
        Init();
        Solve();
    }
    return 0;
}   

猜你喜欢

转载自blog.csdn.net/lunch__/article/details/81429307