I

题意:曹操的船之间有一些桥连接,现在周瑜想把这些连接的船分成两部分,不过他只能炸毁一座桥,并且每座桥上有士兵看守,问,他最少需要排多少士兵去炸桥如果不能做到,输出‘-1’
注意:此题有好几个坑,第一个输入桥守卫是0的话也得排一个士兵
如果一开始桥就是不连通的就不用派士兵了,直接输出 0
**************************************************************
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

const int MAXN = 1e3+5;
const int oo = 1e9;

struct Edge{int v, used, val, next;}e[MAXN*MAXN*2];
int Head[MAXN], cnt;
void AddEdge(int u, int v, int val)
{
    if(val == 0)val = 1;
    e[cnt].v = v;
    e[cnt].used = false;
    e[cnt].val = val;
    e[cnt].next = Head[u];
    Head[u] = cnt++;
}

int low[MAXN], dfn[MAXN], Index;
int Min;

void InIt(int N)
{
    cnt = Index = 0;
    Min = oo;
    for(int i=0; i<=N; i++)
    {
        Head[i] = -1;
        dfn[i] = 0;
    }
}
void Tarjan(int u)
{
    dfn[u] = low[u] = ++Index;

    for(int j=Head[u]; j!=-1; j=e[j].next)
    {
        if( e[j].used == false )
        {
            int  v = e[j].v;

            e[j].used = e[j^1].used = true;

            if( !dfn[v] )
            {
                Tarjan(v);
                low[u] = min(low[u], low[v]);

                if(low[v] > dfn[u])
                    Min = min(Min, e[j].val);
            }
            else
                low[u] = min(low[u], dfn[v]);
        }
    }
}

int main()
{
    int N, M;

    while(scanf("%d%d", &N, &M), N+M)
    {
        int u, v, val;

        InIt(N);

        while(M--)
        {
            scanf("%d%d%d", &u, &v, &val);
            AddEdge(u, v, val);
            AddEdge(v, u, val);
        }

        Tarjan(1);

        for(int i=1; i<=N; i++)
        {
            if(dfn[i] == 0)
                Min = 0;
        }

        if(Min == oo)
            printf("-1 ");
        else
            printf("%d ", Min);
    }

    return 0; 

}

原文地址:https://www.cnblogs.com/liuxin13/p/4693856.html