P1629邮递员送信-题解

Problem

对于一个n个顶点的有向强连通图,求\sum_{i=2}^n(dis_{1,i}+dis_{i,1}).

题目

Solution

对于dis_{1,i},可以用spfa或dijstra求出单源最短路,对于dis_{i,1},可以将边反向后求最短路。

本人用的是spfa,要注意手搓循环队列的时候,不是front < rear,而是front != rear,偷偷告诉你我不太会写dijstra

同时,最好不写双份代码,不便于调试。

Code

#include
#include
#define MAXN 1005
#define MAXM 100010
#define INF 999999999
using namespace std;
int read(){
    int res = 0, ch = getchar();
    bool flag = false;
    while((ch < '0' || ch > '9') && ch != '-') ch = getchar();
    if(ch == '-'){
        flag = true;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        res = (res << 3) + (res << 1) + (ch - '0');
        ch = getchar();
    }
    return flag ? -res : res;
}
void write(int x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x >= 10) write(x / 10);
    putchar(x % 10 + '0');
}
struct Graph {
    int n, cnt, head[MAXN], nxt[MAXM], to[MAXM], w[MAXM], dis[MAXN];
    void add_edge(int a, int b, int c){
        to[++ cnt] = b;
        w[cnt] = c;
        nxt[cnt] = head[a];
        head[a] = cnt;
    }
    void spfa(int k){
        static int que[MAXN];
        static bool inq[MAXN];
        int front = 0, rear = 1;
        memset(inq, false, sizeof inq);
        for(int i = 1;i <= n;i ++)
            dis[i] = (i == k) ? 0 : INF;
        que[front] = k;
        inq[k] = true;
        while(front != rear){
            int cur = que[front];
            front = (front + 1) % MAXN;
            inq[cur] = false;
            for(register int i = head[cur];i;i = nxt[i])
                if(dis[to[i]] > dis[cur] + w[i]){
                    dis[to[i]] = dis[cur] + w[i];
                    if(!inq[to[i]]){
                        que[rear] = to[i];
                        rear = (rear + 1) % MAXN;
                        inq[to[i]] = true;
                    }
                }
        }
    }
} gra1, gra2;
int main(){
    gra1.n = gra2.n = read();
    int m = read(), ans = 0;
    for(register int i = 0;i < m;i ++){
        int a = read(), b = read(), c = read();
        gra1.add_edge(a, b, c);
        gra2.add_edge(b, a, c);
    }
    gra1.spfa(1);
    gra2.spfa(1);
    for(register int i = 2;i <= gra1.n;i ++)
        ans += gra1.dis[i] + gra2.dis[i];
    write(ans);
}

你可能感兴趣的:(最短路)