问题:给出当前点和任务点,求当前点到点1的距离加上点1到任务点的距离。所以直接spfa一遍再分开加就行。
分析:数据过大,所以必须使用优化。利用堆和优先队列,已经book标记。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=1e6+1000;
int inf=0x3f3f3f3f;
ll head[N],dis[N],vis[N],num=0;
struct node
{
ll nex,to,s;
}l[N+1000];
//priority_queue<pll,vector<pll>,greater<pll> >q;
void add(ll x,ll y,ll z)
{
num++;
l[num].to=y;
l[num].nex=head[x];
l[num].s=z;
head[x]=num;
}
void spfa(ll x)
{
ll t;
//queue<int>q;
priority_queue<pll,vector<pll>,greater<pll> >q;
q.push({0,1});//x到遍历点的距离 遍历点
memset(vis,0,sizeof(vis));
dis[x]=0;
q.push({0,1});
while(!q.empty())
{
int s=q.top().first;//这个点到x的距离
int ss=q.top().second;//这个点的编号
q.pop();
if(vis[ss]) //从x点开始,选择一个点后已经知道当前最短路了,再更新那就是环了
continue;
vis[ss]=1;
for(int i=head[ss];i!=-1;i=l[i].nex)
{
t=l[i].to;
if(dis[t]>dis[ss]+l[i].s&&!vis[t])
{
dis[t]=dis[ss]+l[i].s;
q.push({dis[t],t});
}
}
}
}
int main()
{
int m,t,a,b,c,n;
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
//for(int i=0;i<=n+100;i++)
//dis[i]=inf;// 这样写答案错误!!!! 有样例过不去
memset(dis,inf,sizeof(dis));
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
spfa(1);
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&a,&b);
printf("%lld\n",dis[a]+dis[b]);//注意是%lld
}
}