POJ 1511 SPFA+邻接表 Invitation Cards

 题目大意:

计算从 1 点 到 其他所有点的 往返距离之和, 因为是 有向图, 所以我们需要将图反存 一次, 然后求两次单源最短路, 结果就出来了。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define INF 0xffffffff
#define maxn 1000005

struct Edge
{
    int w, e;
};

int UseCount[maxn], m ,n;
bool Use[maxn];
long long dist[2][maxn];

vector<vector<Edge> > G[2];

void Init()
{
    G[0].clear();
    G[1].clear();
    G[0].resize(n+1);
    G[1].resize(n+1);
    for(int i=1; i<=n; i++)
    {
        dist[1][i] = dist[0][i] = INF, Use[i] = false;
    }
}
long long Spfa(int k)
{
    Edge P, Pn;
    P.w = 0, P.e = 1;
    dist[k][1] = 0;
    queue<Edge>Q;
    Q.push(P);

    while( !Q.empty() )
    {
        P = Q.front();
        Q.pop();
        Use[P.e] = false;
        int len = G[k][P.e].size();

        for(int i=0; i<len; i++)
        {
            Pn = G[k][P.e][i];

            if(dist[k][Pn.e] > dist[k][P.e] + Pn.w)
            {
                dist[k][Pn.e] = dist[k][P.e] + Pn.w;
                if( !Use[Pn.e] )
                {
                    Q.push(Pn);
                    Use[Pn.e] = true;
                }
            }
        }
    }

    long long sum = 0;

    for(int i=1; i<=n; i++)
        sum += dist[k][i];
    return sum;
}

int main()
{
    int T;
    Edge P;
    scanf("%d",&T);
    while(T--)
    {

        scanf("%d%d",&n,&m);
        Init();
        for(int i=0; i<m; i++)
        {
            int a, b, c;
            scanf("%d%d%d",&a,&b,&c);
            P.e = b, P.w = c;
            G[0][a].push_back(P);
            P.e = a;
            G[1][b].push_back(P);
        }
        
        long long sum = 0;
        
        sum += Spfa(0);
        sum += Spfa(1);

        printf("%I64d
",sum);
    }
    return 0;
}
 
原文地址:https://www.cnblogs.com/chenchengxun/p/4151796.html