HDU 1535 Invitation Cards 单源最短路

题意:一个中心原点1,给你n个点,m条边,问你从1到2-n的每一个点,加上从2-n返回1点的距离总和的最小值是多少?


想法:比较好想,去:单源最短路,从1开始,所有点自动跑完,反向建边,就不需要从枚举每一个2-n的点到1的最短路。求和即可。


#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define inf 0x7fffffff
using namespace std;
const int nodes=1000000+50;
const int edges=1000000+50;
struct node
{
    int v,w,next;
}e[edges];
int head[nodes],cnt,sum;
int n,m;
int a[edges],b[edges],c[edges];
void Init()
{
    memset(head,-1,sizeof(head));
    cnt=0;
}
void add(int u,int v,int w)
{
    e[cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
void spfa()
{
    queue<int>q;
    while(!q.empty()) q.pop();
    int dis[nodes];
    bool vis[nodes];
    for(int i=1;i<=n;i++)
    {
        dis[i]=inf;
        vis[i]=0;
    }
    dis[1]=0;
    vis[1]=1;
    q.push(1);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i+1;i=e[i].next)
        {
            int v=e[i].v;
            if(dis[v]>dis[u]+e[i].w)
            {
                dis[v]=dis[u]+e[i].w;
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
    sum+=dis[i];
}
int main()
{
    int test;
    scanf("%d",&test);
    while(test--)
    {
        Init();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a[i],&b[i],&c[i]);
            add(a[i],b[i],c[i]);
        }
        sum=0;
        spfa();
        Init();
        for(int i=1;i<=m;i++)
        {
            add(b[i],a[i],c[i]);
        }
        spfa();
        printf("%d\n",sum);
    }
    return 0;
}

你可能感兴趣的:(HDU 1535 Invitation Cards 单源最短路)