1. 程式人生 > >Caocao's Bridges HDU - 4738(Tarjan求割邊模板題)

Caocao's Bridges HDU - 4738(Tarjan求割邊模板題)

題目連結

題目意思:
求割邊

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 1010;

int n, m, tot, num;
int head[maxn], dfn[maxn], low[maxn];
bool bridge[1000100 * 2];

struct node
{
    int v, w, next;
}edge[1000100 * 2];

inline void add(int
u, int v, int w) { edge[tot].v = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++; } inline void Init() { tot = 2; num = 0; memset(head, -1, sizeof(head)); memset(dfn, -1, sizeof(dfn)); memset(bridge, false, sizeof(bridge)); } void Tarjan(int u, int
edge_id) { dfn[u] = low[u] = ++num; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if(dfn[v] == -1) { Tarjan(v, i); low[u] = min(low[u], low[v]); if(low[v] > dfn[u]) { bridge[
i] = true; bridge[i ^ 1] = true; } } else if(i != (edge_id^1)) { low[u] = min(low[u], dfn[v]); } } } int main() { //freopen("in.txt", "r", stdin); while(cin >> n >> m && n && m) { Init(); int u, v, w; for(int i = 1; i <= m; ++ i) { scanf("%d%d%d", &u, &v, &w); add(u, v, w); add(v, u, w); } Tarjan(1, 0); bool flag = false; //如果圖本身就不是連通圖,就沒必要派人去炸橋了,答案直接就是0 for(int i = 1; i <= n; ++ i) { if(dfn[i] == -1) { flag = true; break; } } if(flag) { cout << 0 << endl; continue; } //如果圖是連通的 int mins = 0x3f3f3f3f; for(int i = 2; i < tot; i += 2) { if(bridge[i]) { mins = min(mins, edge[i].w); } } if(mins == 0x3f3f3f3f) { cout << -1 << endl; } else { if(mins == 0)  //還要看是不是守橋的人數為0,如果是這樣的話,那也要派一個人去 mins = 1; cout << mins << endl; } } return 0; }