Caocao 교량 [HDU - 4738] Tarjan 다리 요청 (절삭 날)]

주제 링크


  적벽의 전투에서 조조는 제갈량과 주유를 격파했다. 그러나 그는 포기하지 않을 것이다. 그는 또 다른 아이디어를 제안 그래서 조조의 군대는 여전히 좋은 물 전쟁이 아니다. 그는이 섬에 근거하여,이 조조의 군대 주유의 군대를 공격하기 쉽고, 장강의 많은 섬을 만들었습니다. 조조는 섬을 연결하는 다리를 건설했다. 모든 섬이 다리로 연결되어있는 경우, 그래서 조조의 군대는 아주 쉽게이 섬에 배포 할 수 있습니다. 그는 하나 개 이상의 섬은 다른 섬에서 분리 될 수 있도록, 카오 카오 다리의 일부를 파괴하고 싶어 그래서 주유은 참을 수있다. 그는 단지 다리를 파괴 할 수 있도록하지만, 단 하나의 제갈량의, 주유는 폭탄을 떠났다. 주유는 다리를 파괴하는 폭탄을 수행하기 위해 전송해야합니다. 다리를 지키고있을 수 있습니다. 군인의 수는 달리 임무는 실패, 다리를 지키는 폭격 팀의 수보다 낮은 수 없습니다. 적어도 주유를 필요로 얼마나 많은 군인 알아 주시기 바랍니다.

세부 사항 :

  이 보호에는 다리가 될,하지만 여전히이 경우 대답은 하나, 사람이 아 폭발물에 대해 이동 할 수 있습니다.

  항상 더 많은 연결 그래프 된 경우에, 당신은 타격에 사람을 찾을 필요가 없습니다,이 시간은 답은 0이다.

  나머지는 Tarjan이 다리의 무향 그래프를 추구합니다.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
//#include <unordered_map>
//#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define eps 1e-8
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 1e3 + 7;
int N, M, head[maxN], cnt;
bool vis[(maxN * maxN) << 1];
struct Eddge
{
    int nex, to, val;
    Eddge(int a=-1, int b=0, int c=0):nex(a), to(b), val(c) {}
}edge[(maxN * maxN) << 1];
inline void addEddge(int u, int v, int w)
{
    edge[cnt] = Eddge(head[u], v, w); vis[cnt] = false;
    head[u] = cnt++;
}
inline void _add(int u, int v, int w) { addEddge(u, v, w); addEddge(v, u, w); }
int dfn[maxN], low[maxN], tot, Stap[maxN], Stop, Belong[maxN], Bcnt;
bool instack[maxN] = {false};
void Tarjan(int u)
{
    dfn[u] = low[u] = ++tot;
    Stap[++Stop] = u;
    instack[u] = true;
    for(int i=head[u], v; ~i; i=edge[i].nex)
    {
        if(vis[i]) continue;
        vis[i] = vis[i ^ 1] = true;
        v = edge[i].to;
        if(!dfn[v])
        {
            Tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(instack[v]) low[u] = min(low[u], dfn[v]);
    }
    if(low[u] == dfn[u])
    {
        Bcnt++;
        int v;
        do
        {
            v = Stap[Stop--];
            Belong[v] = Bcnt;
            instack[v] = false;
        } while(u ^ v);
    }
}
inline void init()
{
    cnt = tot = Stop = Bcnt = 0;
    for(int i=1; i<=N; i++) { head[i] = -1; dfn[i] = 0; instack[i] = false; Belong[i] = 0; }
}
int main()
{
    while(scanf("%d%d", &N, &M) && (N | M))
    {
        init();
        for(int i=1, u, v, w; i<=M; i++)
        {
            scanf("%d%d%d", &u, &v, &w);
            _add(u, v, w);
        }
        int tim = 0;
        for(int i=1; i<=N; i++) if(!dfn[i]) { Tarjan(i); tim ++; }
        int ans = INF;
        for(int u=1; u<=N; u++)
        {
            for(int i=head[u], v; ~i; i=edge[i].nex)
            {
                v = edge[i].to;
                if(Belong[u] ^ Belong[v]) ans = min(ans, edge[i].val);
            }
        }
        if(!ans) ans = 1;
        if(tim > 1) ans = 0;
        printf("%d\n", ans < INF ? ans : -1);
    }
    return 0;
}

 

게시 된 885 개 원래 기사 · 원 찬양 1058 ·은 120,000 + 조회수

추천

출처blog.csdn.net/qq_41730082/article/details/105253574