HDU SPFA算法 Invitation Cards

来源:互联网 发布:华为java编码规范考试 编辑:程序博客网 时间:2024/05/09 17:50

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1535

分析:

         题意:求1点到其它点的最短距离之和+其它点到1点的最短距离之和

         前面一部分直接用SPFA算法求出,而后一部分可用一数组存放反向边

       (所有边的方向都反一下),利用反向边SPFA求出1点到其它点距离即可。


#include <iostream>#include <cstdio>#include <cmath>#include <cstdlib>#include <string>#include <cstring>#include <algorithm>#include <queue>using namespace std;const int inf = 0xfffffff;const int maxn = 1000000+10;bool vis[maxn];int h1[maxn],h2[maxn],dis[maxn];int t1,t2,n,m;struct node{    int x,v,next;}f1[maxn],f2[maxn];///f1存放顺向边, f2存放反向边void init(){    t1=t2=0;    memset(h1,-1,sizeof(h1));    memset(h2,-1,sizeof(h2));}void addnode_1(int a,int b,int c){    f1[t1].x=b;    f1[t1].v=c;    f1[t1].next=h1[a];    h1[a]=t1++;}void addnode_2(int a,int b,int c){    f2[t2].x=b;    f2[t2].v=c;    f2[t2].next=h2[a];    h2[a]=t2++;}int spfa(node F[ ],int H[ ]){    memset(vis,false,sizeof(vis));    for(int i=1;i<=n;++i)        dis[i]=inf;    dis[1]=0;    vis[1]=true;    queue<int>M;    M.push(1);    while(!M.empty()){        int now=M.front(); M.pop();        vis[now]=false;        for(int i=H[now];i!=-1;i=F[i].next){            int next=F[i].x;            if(dis[next]>dis[now]+F[i].v){                dis[next]=dis[now]+F[i].v;                if(!vis[next]){                    vis[next]=true;                    M.push(next);                }            }        }    }    int sum=0;    for(int i=2;i<=n;++i)        sum+=dis[i];    return sum;}int main(){    int T;  scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&m);        init();        while(m--){            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            addnode_1(a,b,c);            addnode_2(b,a,c);        }        int ans=spfa(f1,h1)+spfa(f2,h2);        cout<<ans<<endl;    }    return 0;}


原创粉丝点击