Challenges Programming Contest: Roadblocks

Subject to the effect

Here Insert Picture Description

Problem-solving ideas

There are two cases short-circuits. (1) + the shortest one edge by other nodes configured. (2) short-circuits the other edge nodes + a composition. Thus we get two solutions
An ordinary Dijkstra
(1): First of all nodes seeking the shortest path.
(2): 1 according to the situation, determined by the shortest preliminary short-circuits.
(3): The case 2, short-circuits required by the secondary short circuit.

  • Between two nodes note that there may be multiple input side
  • Note that step (3) need to loop until stability is not updated.

Second, the use of a priority queue Dijkstra algorithm
(1): each was removed from the priority queue and is used in the state of the shortest possible time or short-circuited.
(2): each entry of a priority queue states are possible shortest time or short-circuited.
(3): Loop until the priority queue is empty.

Code

  • Ordinary Dijkstra Code
#include<iostream>
#include<vector>
using namespace std;
const int MAXN = 5000+5;
const int INF = 1 << 20;
struct Node
{
    int t;
    int w;
}tmp;
vector<Node> G[MAXN];
int d1[MAXN];
int d2[MAXN];
int visited[MAXN];
int N, R;

void init(int N)
{
    for(int i=1; i<=N; i++)
    {
        d1[i] = INF;
        d2[i] = INF;
        visited[i] = 0;
    }
}
void get_second_d(int v)
{
    //找最短路
    d1[v] = 0;
    visited[v] = 1;
    for(int i=0; i<G[v].size();i++)
    {
        int next_v = G[v][i].t;
        d1[next_v] = min(G[v][i].w, d1[next_v]);
    }

    for(int i=0; i<N; i++)
    {
        int min_d = INF;
        int min_v;
        for(int j=1; j<=N; j++)
        {
            if(!visited[j] && min_d > d1[j])
            {
                min_d = d1[j];
                min_v = j;

            }
        }

        visited[min_v] = 1;
        for(int j=0; j<G[min_v].size(); j++)
        {
            int next_v = G[min_v][j].t;
            if(!visited[next_v] && min_d + G[min_v][j].w < d1[next_v])
                d1[next_v] = min_d +G[min_v][j].w;
        }
    }

    // 更具最短路初步找到一部分次短路
    for(int i=1; i<=N;i++)
    {
        for(int j=0; j<G[i].size(); j++)
        {
            int next_v = G[i][j].t;
            int length = d1[i] + G[i][j].w;
            if(length > d1[next_v] && length < d2[next_v])
                d2[next_v] = length;
        }
    }

    // 根据次短路最后确认次短路
    while(true)
    {
        int update = 0;
        for(int i=1; i<=N;i++)
        {
            for(int j=0; j<G[i].size(); j++)
            {
                int next_v = G[i][j].t;
                int length = d2[i] + G[i][j].w;
                if(length > d1[next_v] && length < d2[next_v])
                {
                    d2[next_v] = length;
                    update = 1;
                }
            }
        }
        if(!update)
            break;
    }
}
int main()
{
    int s,e,w;
    cin >> N >> R;
    init(N);
    while(R--)
    {
        cin >> s >> e >> w;
        tmp.w = w;

        tmp.t = e;
        G[s].push_back(tmp);
        tmp.t = s;
        G[e].push_back(tmp);
    }
    get_second_d(1);
    cout << d2[N] << endl;
    return 0;

}

  • Priority team 列迪杰斯特拉 Code
#include<iostream>
#include<vector>
#include<queue>
using namespace std;

const int MAXN = 5005;
const int inf = 1 << 20;
int d1[MAXN], d2[MAXN];
struct Node
{
    int t,w;
}tmp;
vector<Node> G[MAXN];
typedef pair<int, int> P;

priority_queue<P, vector<P>, greater<P> >PQ;
void djstl2(int v)
{
    PQ.push(P(0, v));
    while(!PQ.empty())
    {
        P top = PQ.top();
        PQ.pop();
        int now_v = top.second;
        int now_d = top.first;
        if(now_d > d2[now_v]) continue;
        for(int j=0; j<G[now_v].size(); j++)
        {
            Node e = G[now_v][j];
            int next_v = e.t;
            int next_d = now_d + e.w;
            if(next_d < d1[next_v])
            {
                swap(next_d, d1[next_v]);
                PQ.push(P(d1[next_v], next_v));
            }
            if(next_d > d1[next_v] && next_d < d2[next_v])
            {
                d2[next_v] = next_d;
                PQ.push(P(d2[next_v], next_v));
            }
        }
    }
}
int main()
{
    int N, R;
    cin >> N >> R;
    int a, b, w;
    for(int i=1; i<=N; i++)
    {
        d1[i] = inf;
        d2[i] = inf;
    }
    while(R--)
    {
        cin >> a >> b >> w;
        tmp.w = w;
        tmp.t = b;
        G[a].push_back(tmp);

        tmp.t = a;
        G[b].push_back(tmp);
    }
    djstl2(1);
    cout << d2[N] << endl;
}

Guess you like

Origin blog.csdn.net/Wangpeiyi9979/article/details/93676195