hdu 1535 Invitation Cards(SPFA)

来源:互联网 发布:网络充值卡代理 编辑:程序博客网 时间:2024/05/20 14:28

hdu 1535Invitation Cards

题意:在一个有向图中,一个人需要走完所有景点,然后返回,求起点到所有景点的最短路+所有景点到起点的最短路。

解题思路:正向求一次SPFA,然后将所有边反向,再求一次SPFA。

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <cmath>#include <vector>#include <queue>#include <numeric>#include <map>using namespace std;#define LL long long#define M 1002#define N 1000002#define INF 1<<29#define CLS(x,v) memset(x,v,sizeof(x))#define FOR(i,a,n)  for(int i=(a);i<=(n);++i)//建立反向边,求两遍SPFA//注意一开始 在函数里面开 10^6 大的数组,会堆栈溢出int headlist1[N];int headlist2[N];struct EDGE{  int to,w,next;}e1[N],e2[N];int n;bool vis[N];int dist[N];int spfa(int s,int head[],EDGE e[]){    queue<int> Q;    Q.push(s);    FOR(i,0,N)dist[i]=INF;    CLS(vis,0);    dist[s]=0;    int pre,t;    while(!Q.empty())    {        pre=Q.front();        Q.pop();        vis[pre]=0;        for(int i=head[pre];i!=-1;i=e[i].next)        {            t=e[i].to;            if(dist[t]>dist[pre]+e[i].w)            {                dist[t]=dist[pre]+e[i].w;                if(!vis[t])                {                    Q.push(t);                    vis[t]=1;                }            }        }    }    int ret=0;    for(int i=1;i<=n;i++)        ret=ret+dist[i];    return ret;}int main(){    int T,m;    cin>>T;    int s,t,w;    while(T--)    {        scanf("%d%d",&n,&m);        CLS(headlist1,-1);        CLS(headlist2,-1);        for(int i=1;i<=m;i++)        {            scanf("%d%d%d",&s,&t,&w);            e1[i].to=t;            e1[i].w=w;            e1[i].next=headlist1[s];            headlist1[s]=i;//记录边的编号            //建立反向边            e2[i].to=s;            e2[i].w=w;            e2[i].next=headlist2[t];            headlist2[t]=i;        }        printf("%d\n",spfa(1,headlist1,e1)+spfa(1,headlist2,e2));    }    return 0;}





0 0
原创粉丝点击