Estradas e rotas (caminho mais curto + classificação topológica)

Título

Existem algumas bordas direcionadas e algumas bordas não direcionadas. Sabendo que não há loop, encontre a menor distância do ponto de partida aos outros pontos.

intervalo de dados

Cartão spfa

Ideias (consulte acwing)

Esta questão tem um cérebro maior, mas um pensamento mais profundo. Como não há loop, alguns pontos conectados por arestas não direcionadas podem ser considerados um bloco e, então, esses blocos formam um gráfico direcionado por meio de arestas direcionadas. Em outras palavras, o local é um gráfico não direcionado e o global é um gráfico direcionado.
Em seguida, a classificação topológica é feita no global e Dijkstra é feita dentro do bloco. As etapas do algoritmo são as seguintes:

  • Primeiro insira todas as estradas de mão dupla e, em seguida, encontre todos os blocos conectados de maneira semelhante e calcule duas matrizes: a qual bloco conectado cada ponto pertence e quais pontos cada bloco conectado possui.
  • Insira todas as rotas e conte o grau de cada bloco conectado ao mesmo tempo.
  • Processe cada bloco conectado por vez em ordem topológica. Primeiro adicione os números de todos os blocos conectados com grau 0 à fila.
  • Cada vez que o número do lance de um bloco conectado é retirado do topo da fila
  • Adicione todos os pontos deste bloco ao heap e, em seguida, execute o algoritmo de Dijkstra em todos os pontos do heap.
  • Retire o ponto com a menor distância na pilha de cada vez
  • Em seguida, atravesse todos os vizinhos j de ver. Se id [ver] == id [j], então se j pode ser atualizado, insira j na pilha; se id [ver]! = Id [j], então adicione id [j] O grau deste bloco conectado é reduzido em 1. Se for reduzido para 0, ele é inserido na fila classificada topologicamente.

Código

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

using namespace std;

const int N = 25010, M = 150010, inf = 0x3f3f3f3f;

typedef pair<int,int> pii;

int n,R,P,S;
int h[N], e[M], ne[M], w[M], idx;
int dist[N], id[N];
bool st[N];
int bin[N];
int bcnt;
vector<int> block[N];
queue<int> que;

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

void dfs(int u,int k)
{
    
    
    block[k].push_back(u);
    id[u] = bcnt;
    for(int i=h[u];~i;i=ne[i]){
    
    
        int j = e[i];
        if(!id[j]){
    
    
            dfs(j,k);
        }
    }
}

void dijkstra(int bid)
{
    
    
    priority_queue<pii,vector<pii>,greater<pii>> heap;
    for(auto u:block[bid]){
    
    
        heap.push({
    
    dist[u],u});
    }
    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];
            if(id[j]!=id[ver]&&--bin[id[j]]==0) que.push(id[j]);
            if(dist[j]>distance+w[i]){
    
    
                dist[j] = distance + w[i];
                if(id[j]==id[ver]){
    
    
                    heap.push({
    
    dist[j],j});
                }
            }
        }
    }
}

void topsort()
{
    
    
    memset(dist,0x3f,sizeof(dist));
    dist[S] = 0;
    for(int i=1;i<=bcnt;i++)
        if(!bin[i])
            que.push(i);
    while(que.size()){
    
    
        int t = que.front();
        que.pop();
        dijkstra(t);
    }
}

int main()
{
    
    
    cin >> n >> R >> P >> S;
    memset(h,-1,sizeof(h));
    while(R--){
    
    
        int a,b,c;
        cin >> a >> b >> c;
        add(a,b,c), add(b,a,c);
    }
    for(int i=1;i<=n;i++)
        if(!id[i])
        {
    
    
            bcnt ++;
            dfs(i,bcnt);
        }
    while(P--){
    
    
        int a,b,c;
        cin >> a >> b >> c;
        add(a,b,c);
        bin[id[b]] ++;
    }
    topsort();
    for(int i=1;i<=n;i++){
    
    
        if(dist[i]>inf/2) cout << "NO PATH" << endl;
        else cout << dist[i] << endl;
    }
    return 0;
}

Acho que você gosta

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