题目大意:给你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!!!!!!!!!!!!!!!!!!!!!!!!!!!!