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

来源:互联网 发布:淘宝女装店的现状分析 编辑:程序博客网 时间:2024/05/20 14:25

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

有向图, 有个源叫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);    }}