Línea de comunicación (camino más corto + dos puntos)

Título

Dado un gráfico no dirigido, puede seleccionar una ruta y configurarla kkk el peso del borde pasa a ser0 00 para minimizar el valor máximo de los bordes restantes. Encuentra este mínimo.

práctica

Cuando el valor máximo es el más pequeño, primero considere la respuesta de dos puntos, dos puntos. Durante la dicotomía, si es mayor que la mitadEl número de lados de m i d es mayor quekkk , entonces el valor mínimo debe ser mayor que la respuesta actual.

Código 1 (Dijkstra)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int N = 1010, M = 20010, inf = 0x3f3f3f3f;

typedef pair<int,int> pii;

int n,m,k;
int h[N], e[M], ne[M], w[M], idx;
int dist[N];
bool st[N];

void add(int a,int b,int c)
{
    
    
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}

bool check(int limit)
{
    
    
    memset(dist,0x3f,sizeof(dist));
    memset(st,false,sizeof(st));
    dist[1] = 0;
    priority_queue<pii,vector<pii>,greater<pii>> heap;
    heap.push({
    
    0,1});
    while(heap.size()){
    
    
        auto t = heap.top();
        heap.pop();
        int ver = t.second, distance = t.first;
        if(st[ver]) continue;
        st[ver] = true;
        for(int i=h[ver];~i;i=ne[i]){
    
    
            int j = e[i];
            int x = w[i] > limit;
            if(dist[j]>distance+x){
    
    
                dist[j] = distance + x;
                heap.push({
    
    dist[j],j});
            }
        }
    }
    return dist[n] <= k;
}

int main()
{
    
    
    cin >> n >> m >> k;
    memset(h,-1,sizeof(h));
    while(m--){
    
    
        int a,b,c;
        cin >> a >> b >> c;
        add(a,b,c), add(b,a,c);
    }
    int l = 0, r = 1e6 + 1;
    while(l<r){
    
    
        int mid =  l + r >> 1;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    if(r==1e6+1) cout << -1 << endl;
    else cout << r << endl;
    return 0;
}

Código 2 (spfa)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

const int N = 1010, M = 20010, inf = 0x3f3f3f3f;

int n,m,k;
int h[N], e[M], ne[M], w[M], idx;
int dist[N];
bool st[N];

void add(int a,int b,int c)
{
    
    
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}

bool check(int limit)
{
    
    
    memset(dist,0x3f,sizeof(dist));
    memset(st,false,sizeof(st));
    dist[1] = 0;
    queue<int> que;
    que.push(1);
    st[1] = true;
    while(que.size()){
    
    
        int t = que.front();
        que.pop();
        st[t] = false;
        for(int i=h[t];~i;i=ne[i]){
    
    
            int j = e[i];
            int distance = w[i] > limit;
            if(dist[j]>dist[t]+distance){
    
    
                dist[j] = dist[t] + distance;
                if(!st[j]){
    
    
                    st[j] = true;
                    que.push(j);
                }
            }
        }
    }
    return dist[n] <= k;
}

int main()
{
    
    
    cin >> n >> m >> k;
    memset(h,-1,sizeof(h));
    while(m--){
    
    
        int a,b,c;
        cin >> a >> b >> c;
        add(a,b,c), add(b,a,c);
    }
    int l = 0, r = 1e6 + 1;
    while(l<r){
    
    
        int mid =  l + r >> 1;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    if(r==1e6+1) cout << -1 << endl;
    else cout << r << endl;
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_43634220/article/details/108606138
Recomendado
Clasificación