hdu1535 SPFA

来源:互联网 发布:手机上怎么改淘宝评价 编辑:程序博客网 时间:2024/05/09 12:38

题意:有n-1的站点和原点,然后原点有n-1个人要分别走到所有的站点

然后再从这些站点走回来 问最少总共要走多少路

解法:首先是要走出去 这个很简单就是裸的最短路,然后走完最短路以后要从这些点走回来,我们要考虑到

把所有的边反向,这样一来,又变成了从原点走到所有的点  那么再跑一次最短路就可以得到答案了

#include<queue>#include<stdio.h>#include<iostream>#include<algorithm>using namespace std;#define maxn 1111111#define inf 0x3f3f3f3fstruct edge{    int v,w,next;    edge(int v,int w,int next):v(v),w(w),next(next){}    edge(){}}e[1111111];int st,en,n,m;int dis[maxn],vis[maxn],head[maxn],a[maxn],in[maxn];int cnt=0;void init(){    cnt=0;    st=1;en=n;    memset(head,-1,sizeof head);}void add(int u,int v,int w){    e[cnt]=edge(v,w,head[u]);    head[u]=cnt++;}int spfa(){    for(int i=st;i<=en;++i)in[i]=0,vis[i]=0,dis[i]=inf;    queue<int>q;    q.push(st);    dis[st]=0;vis[st]=1;    int u,v;    while(!q.empty())    {                u=q.front();q.pop();vis[u]=0;//        printf("u:%d head:%d\n",u,head[u]);                if(++in[u]>n)return 0;        for(int i=head[u];i!=-1;i=e[i].next){            v=e[i].v;                        if(dis[v]>dis[u]+e[i].w){                dis[v]=dis[u]+e[i].w;                if(!vis[v]){                    q.push(v);                    vis[v]=1;                }            }        }            }    return 1;}int from[maxn],to[maxn],va[maxn];int main(){        int _;scanf("%d",&_);    while(_--){                scanf("%d%d",&n,&m);        init();        for(int i=0;i<m;++i){            scanf("%d%d%d",&from[i],&to[i],&va[i]);            add(from[i],to[i],va[i]);        }        spfa();                int sum=0;        for(int i=1;i<=n;++i)sum+=dis[i];        init();        for(int i=0;i<m;++i)add(to[i],from[i],va[i]);        spfa();        for(int i=1;i<=n;++i)sum+=dis[i];        printf("%d\n",sum);    }    return 0;}


0 0
原创粉丝点击