[HDU 1535]Invitation Cards[SPFA反向思维]

题意: (欧洲人自己写的题面就是不一样啊...各种吐槽...果断还是看晕了)

有向图, 有个源叫CCS, 求从CCS到其他所有点的最短路之和, 以及从其他所有点到CCS的最短路之和.

思路:

返回的时候是多个源,但是因为终点只有一个,所以把所有边反向之后, 再SPFA一次源即可.

 

#include<cstdio>

#include<vector>

#include<queue>

const int MAXN=1000000+10;

typedef long long ll;

const ll inf=1e60;

using namespace std;

struct Node{

    int v,w;

};

vector<Node>mp1[MAXN];//正向建图

vector<Node>mp2[MAXN];//反向建图

int n,m;

ll cost[MAXN];



void SPFA(int u,vector<Node>mp[]){

    for(int i=2;i<=n;i++)cost[i]=inf;

    cost[1]=0;

    queue<int>Q;

    Q.push(u);

    while(!Q.empty()){

        int u=Q.front();

        Q.pop();

        for(int i=0;i<mp[u].size();i++){

            int v=mp[u][i].v;

            int w=mp[u][i].w;

            if(cost[v]>cost[u]+w){

                cost[v]=cost[u]+w;

                Q.push(v);

            }

        }

    }

}





int main(){

    int _case;

    scanf("%d",&_case);

    while(_case--){

        scanf("%d%d",&n,&m);

        for(int i=1;i<=n;i++){

            mp1[i].clear();

            mp2[i].clear();

        }

        for(int i=1;i<=m;i++){

            int u,v,w;

            scanf("%d%d%d",&u,&v,&w);

            Node p1,p2;

            p1.v=u,p2.v=v,p1.w=p2.w=w;

            mp1[u].push_back(p2);

            mp2[v].push_back(p1);

        }

        SPFA(1,mp1);//正向求一次

        ll ans=0;

        for(int i=2;i<=n;i++){

            ans+=cost[i];

        }

        SPFA(1,mp2);//反向求一次

        for(int i=2;i<=n;i++){

            ans+=cost[i];

        }

        printf("%lld\n",ans);

    }

    return 0;

}

自己敲一遍:

 

#include <cstdio>

#include <vector>

#include <cstring>

#include <queue>

using namespace std;

typedef long long ll;

const int MAXN = 1e6+5;

const ll INF = 0x3f3f3f3f3f3f3f3fll;

typedef struct node

{

    int v,w;

    node(){}

    node(int _v, int _w):v(_v),w(_w){}

}node;



int n,m;

bool inq[MAXN];

ll cost[MAXN];

vector<node> g1[MAXN],g2[MAXN];



ll SPFA(int op)

{

    memset(cost,0x3f,sizeof(cost));

    memset(inq,false,sizeof(inq));

    cost[1] = 0;

    queue<int> q;

    q.push(1);

    inq[1] = true;

    while(!q.empty())

    {

        int now = q.front();q.pop();

        inq[now] = false;

        for(int i=0,v,w;i<((op==1)?g1[now].size():g2[now].size());i++)

        {

            if(op==1)

            {

                v = g1[now][i].v, w = g1[now][i].w;

            }

            else

            {

                v = g2[now][i].v, w = g2[now][i].w;

            }

            if(cost[v] > cost[now] + w)

            {

                cost[v] = cost[now] + w;

                if(!inq[v])

                {

                    q.push(v);

                    inq[v] = true;

                }

            }

        }

    }

    ll ret = 0;

    for(int i=2;i<=n;i++)

        ret += cost[i];

    return ret;

}



int main()

{

    int T;

    scanf("%d",&T);

    while(T--)

    {

        scanf("%d %d",&n,&m);

        for(int i=1;i<=n;i++)

        {

            g1[i].clear();

            g2[i].clear();

        }

        for(int i=0,u,v,w;i<m;i++)

        {

            scanf("%d %d %d",&u,&v,&w);

            g1[u].push_back(node(v,w));

            g2[v].push_back(node(u,w));

        }

        ll ans = 0;

        ans += SPFA(1);

        ans += SPFA(2);

        printf("%d\n",(int)ans);

    }

}


 

 

 

 

你可能感兴趣的:(SPFA)