最先端のアルゴリズムTarjan

定義

(無向グラフで):省略された場合、エッジは、通信ブロックの数を増加させる、請求連結グラフにおいて、我々は、この縁部またはブリッジの刃先と呼ばれます。

アルゴリズム

[U DFN [V]>だけ低いと判断Tarjan、 ] (U親、Vサブ)の
説明:場合は親または子ノードが同じ道を行くしない場合は、親ノードの前にいない点まで、サブノードは、バック親ノードへと前に、壊れユニコムは、最先端の定義に沿って、新しいブロックを生成する唯一の方法と同じように同じ経路を取ることができます。

HDU-4738

この質問内容がたくさん。
図は、最初のリンクか否かを判断し、次にブリッジかどうかを決定する、音符の重い側が干渉ブリッジ、右最小エッジ・ブリッジの最終的な出力(これは、少なくとも一回を送信するために、出力すべき0である場合)と判断されます

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
#define lson x<<1
#define rson x<<1|1
#define ll long long
#define rint register int
#define mid ((st[x].l + st[x].r) >> 1)
using namespace std;
template <typename xxx> inline void read(xxx &x) {
    char c = getchar(),f = 1;x = 0;
    for(;c ^ '-' && !isdigit(c);c = getchar());
    if(c == '-') c = getchar(),f = -1;
    for(;isdigit(c);c = getchar()) x = (x<<1) + (x<<3) + (c ^ '0');
    x *= f;
}
template<typename xxx>void print(xxx x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>9) print(x/10); 
    putchar(x%10+'0');
}
const int maxn = 2002;
const int inf = 0x7fffffff;
const int mod = 1e9 + 7;
struct edge {
    int to,last,val;
//  int fg;
}e[2000002];
int head[maxn],tot;
inline void add(int from,int to,int val) {
    ++tot;
    e[tot].to = to;
//  e[tot].fg = 0;
    e[tot].val = val;
    e[tot].last = head[from];
    head[from] = tot;
}
int n,m;
int dfn[maxn],low[maxn],cnt;
int mark[2000002],mk;
inline void tarjan(int x,int in_edge) {//通过in_edge到达x 
    dfn[x] = low[x] = ++cnt;
    for(rint i = head[x];i;i = e[i].last) {
        if(!dfn[e[i].to]) {
            tarjan(e[i].to,i);
            if(low[x] > low[e[i].to]) low[x] = low[e[i].to];
            if(low[e[i].to] > dfn[x]) {//子节点无法到达我及我之前,则联系我与子节点的边为桥 
//这个判断可以防重边对桥的干扰,假设原图有一个桥,tarjan时绝对无法回到父节点及之前节点,
//但是有重边时 子节点通过重边“回到父节点”更新low[e[i].to] == dfn[x],结果无法被判为桥 
//              e[i].fg = e[i^1].fg = 1;//可这样记录重边 
                mark[++mk] = e[i].val;
            }
        }
        else if(i ^ (in_edge ^ 1) && dfn[e[i].to] < low[x]) low[x] = dfn[e[i].to];//保证无重边时不会被父亲更新 
    }
}
int main()
{
    while(1) {
        tot = 1;
        mk = 0;
        cnt = 0;
        read(n);read(m);
        if(!n && !m) break;
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(head,0,sizeof(head));
        for(rint i = 1;i <= m; ++i) {
            int a,b,c;
            read(a);read(b);read(c);
            add(a,b,c);add(b,a,c);
        }   
        int k = 0;
        for(rint i = 1;i <= n; ++i) {
            if(!dfn[i]) {
                tarjan(i,0);
                ++k;
            }
        }
        if(mk == 0) {//无桥, 
            printf("-1\n");
        } else {
            stable_sort(mark + 1,mark + mk + 1);
            if(k > 1) printf("0\n");
            else if(mark[1])printf("%d\n",mark[1]);
            else printf("1\n");//没人守也要派一个人去占领 
        }
    }   
    return 0;
}
/*
6 8
1 2 1
2 1 2
1 3 3
3 4 4
4 1 5
2 5 6
2 6 7
5 6 8

6 7
1 2 1
1 3 3
3 4 4
4 1 5
2 5 6
2 6 7
5 6 8
*/

おすすめ

転載: www.cnblogs.com/Thomastine/p/11779603.html