HDU 4738 Caocao's Bridges (Bridge, cualquier operación de bit debe estar entre corchetes, porque hay bordes pesados, así que use la estrella hacia adelante)

HDU 4738 Caocao's Bridges (Bridge, cualquier operación de bit debe estar entre corchetes, porque hay bordes pesados, así que use la estrella hacia adelante)

Caocao fue derrotado por Zhuge Liang y Zhou Yu en la batalla de Chibi. Pero él no se rendiría. El ejército de Caocao todavía no era bueno en las batallas de agua, así que se le ocurrió otra idea. Construyó muchas islas en el río Changjiang y, basándose en esas islas, el ejército de Caocao podría atacar fácilmente a la tropa de Zhou Yu. Caocao también construyó puentes que conectan islas. Si todas las islas estuvieran conectadas por puentes, el ejército de Caocao podría desplegarse de manera muy conveniente entre esas islas. Zhou Yu no podía soportar eso, por lo que quería destruir algunos puentes de Caocao para que una o más islas estuvieran separadas de otras islas. Pero Zhou Yu solo tenía una bomba que dejó Zhuge Liang, por lo que solo pudo destruir un puente. Zhou Yu debe enviar a alguien que lleve la bomba para destruir el puente. Puede que haya guardias en los puentes. El número de soldados del equipo de bombardeo no podía ser menor que el número de guardias de un puente, o la misión fracasaría. Por favor, averigüe al menos cuántos soldados tiene que enviar Zhou Yu para completar la misión de separación de la isla.

Entrada
No hay más de 12 casos de prueba.
En cada caso de prueba:
la primera línea contiene dos números enteros, N y M, lo que significa que hay N islas y M puentes. Todas las islas están numeradas de 1 a N. (2 <= N <= 1000, 0 <M <= N2) Las
siguientes M líneas describen M puentes. Cada línea contiene tres números enteros U, V y W, lo que significa que hay un puente que conecta la isla U y la isla V, y hay guardias W en ese puente. (U ≠ V y 0 <= W <= 10,000)
La entrada termina con N = 0 y M = 0.

Salida
Para cada caso de prueba, imprima el número mínimo de soldado que Zhou Yu tuvo que enviar para completar la misión. Si Zhou Yu no pudo tener éxito de ninguna manera, imprima -1 en su lugar.

Pregunta: Cao Cao tiene un gráfico no dirigido con algunos bordes en la imagen. Zhou Yu ahora quiere enviar a algunas personas a hacer explotar un borde para que el gráfico no dirigido de Cao Cao se divida en diferentes partes. Cada borde de Cao Cao tiene guardias. Zhou Yu envió El número de personas no puede ser menor que el número de guardias en el costado, pregunte cuántas personas deben enviarse al menos.

  • Preste atención al procesamiento lateral pesado, use la estrella de cadena hacia adelante.
  • Cuando el guardia es 0, también debe enviar a una persona;
  • Si la imagen original no está conectada (tarjan varias veces), no es necesario enviar a alguien, la respuesta es 0.
  • La respuesta genera directamente el peso de borde más pequeño entre todos los puentes.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int N = 500007, M = 5000007, INF = 0x3f3f3f3f;

int n, m;
int bridge[N];
int dfn[N], low[N], num;
int head[N], ver[M], nex[M], edge[M], tot;
int ans;
int dcc_cnt;
int min_bridge;

void init()
{
    
    
    num = tot = dcc_cnt = 0;
    memset(head, -1, sizeof head);
    memset(dfn, 0, sizeof dfn);
    memset(low, 0, sizeof low);
    min_bridge = INF;
}

void add(int x, int y, int z)
{
    
    
    ver[tot] = y;
    edge[tot] = z;
    nex[tot] = head[x];
    head[x] = tot ++ ;
}

void tarjan(int x, int in_edge)
{
    
    
    dfn[x] = low[x] = ++ num;
    for(int i = head[x] ;~i; i = nex[i]){
    
    
        int y = ver[i], z = edge[i];
        if(!dfn[y]){
    
    
            tarjan(y, i);
            low[x] = min(low[x], low[y]);
            if(dfn[x] < low[y]){
    
    
                bridge[i] = bridge[i ^ 1] = true;
                min_bridge = min(min_bridge, z);
            }
        }
        else if(i != (in_edge ^ 1))
            low[x] = min(low[x], dfn[y]);
    }
}

int main()
{
    
    
    while(~scanf("%d%d", &n, &m) && n ){
    
    
        init();

        for(int i = 1; i <= m; ++ i){
    
    
            int x, y ,z;
            scanf("%d%d%d", &x, &y, &z);
            add(x, y, z), add(y, x, z);
        }
        dcc_cnt = 0;
        for(int i = 1; i <= n; ++ i)
            if(!dfn[i])
                tarjan(i, 0), dcc_cnt ++ ;
        
        if(dcc_cnt > 1){
    
    //tarjan多次说明不连通,直接输出0
            printf("0\n");
            continue;
        }
        if(min_bridge == INF)min_bridge = -1;
        else if(min_bridge == 0)min_bridge = 1;
        printf("%d\n", min_bridge);
    }
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_45697774/article/details/108596189
Recomendado
Clasificación