POJ 1511 Invitation Cards

这里写图片描述
这里写图片描述

题目大意:给你T组测试数据 n个站 m条路 后面m行为从哪里到哪里花费好多钱 问你从1到n经过所有站在从n回到1经过所有站最少花费多少钱

解题思路:由于数据量庞大 最后的答案要定义成long long类型 求1到n经过所有站 就是求1到其他站的最少花费多少钱的总和 而n回到1经过所有站 只需要把当原来的站的起始站和终止站换一个位置 在求1到其他站的最少花费多少钱的总和 然后相加便得到了最小值 我们可以采用SPFA最短路径算法来做此题。

下面就上代码了。。。

//Memory: 31516 KB      
//Time: 1797 MS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <vector>
#include <set>

using namespace std;

#define ll long long
#define sc(x) scanf("%d",&x)
#define dsc(x,y) scanf("%d%d",&x,&y)
#define sssc(x)   scanf("%s",s)
#define sdsc(x,y) scanf("%s %s",x,y)
#define ssc(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define pr(x) printf("%d\n",x)
#define FOR(i,n,o) for(int i=o;i<=n;i++)
#define lcr(a,b)  memset(a,b,sizeof(a))


const ll Inf=10e15+2;//以为是long long 所以定义成这么大的
const int maxn=1000005;
int e,n,m,head[maxn],vis[maxn];
ll dis[maxn],ans;//dis也应该为long long类型
struct node
{
    int u;
    int v;
    int w;
    int next;
}q[maxn];
void add(int u,int v,int w)
{
       q[e].u=u;
       q[e].v=v;
       q[e].w=w;
       q[e].next=head[u];
       head[u]=e++;
}
void SPFA(int s)
{
        queue <int> que;
        while(!que.empty())
        que.pop();
       FOR(i,n,1)
       {
           dis[i]=Inf;
           vis[i]=0;
       }
       dis[s]=0;
       vis[s]=1;
       que.push(s);
       while(!que.empty())
       {
            int temp=que.front();
            que.pop();
            vis[temp]=0;
            for(int i=head[temp];i!=-1;i=q[i].next)
            {
                 int v=q[i].v;
                 if(dis[v]>dis[temp]+q[i].w)
                 {
                     dis[v]=dis[temp]+q[i].w;
                     if(!vis[v])
                     {
                         vis[v]=1;
                         que.push(v);
                     }
                 }
            }
       }
}
int main()
{
    int t;
    sc(t);
    while(t--)
    {
          ans=0;
          lcr(head,-1);
          e=0;
          dsc(n,m);
          FOR(i,m,1)
          {
              int a,b,c;
              ssc(a,b,c);
              add(a,b,c);
          }
          SPFA(1);
          FOR(i,n,1)
          {
              ans+=dis[i];
          }
          lcr(head,-1);//初始化
          e=0;//初始化
          FOR(i,m-1,0)//注意你是从0开始的 这里也应该从0开始
          {
              add(q[i].v,q[i].u,q[i].w);
          }
          SPFA(1);
          FOR(i,n,1)
          {
              ans+=dis[i];
          }
        printf("%lld\n",ans);
    }
    return 0;
}

END!!!!!!!!!!!!!!!!!!!!!!!!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值