版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_42369449/article/details/82824696
算法:最短路
难度:NOIP-
用d1,d2,分别跑最短路,跑两遍最短路,取和的最小值输出。
代码如下:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <deque>
#define ll long long
#define N 200005
using namespace std;
int head[N<<1];
ll dis1[N],dis2[N];
struct node
{
int next;
int to;
int val;
}edg[N<<1];
int cnt=1;
void add(int u,int v,int w)
{
edg[cnt].next=head[u];
edg[cnt].to=v;
edg[cnt].val=w;
head[u]=cnt++;
}
void init()
{
memset(head,-1,sizeof(head));
memset(dis1,0x3f3f3f3f,sizeof(dis1));
memset(dis2,0x3f3f3f3f,sizeof(dis2));
cnt=1;
}
int vis1[N],vis2[N];
void spfa1(int rt)
{
deque<int>Q;
Q.push_back(rt);
vis1[rt]=1;
dis1[rt]=0;
while(!Q.empty())
{
int u=Q.front();
Q.pop_front();
for(int i = head[u];i != -1;i = edg[i].next)
{
int to=edg[i].to;
if(dis1[to]>dis1[u]+edg[i].val)
{
dis1[to]=dis1[u]+edg[i].val;
if(!vis1[to])
{
vis1[to]=1;
if(!Q.empty()&&dis1[to]<dis1[Q.front()])
{
Q.push_front(to);
}
else
{
Q.push_back(to);
}
}
}
}
vis1[u]=0;
}
}
void spfa2(int rt)
{
deque<int>Q;
Q.push_back(rt);
vis2[rt]=1;
dis2[rt]=0;
while(!Q.empty())
{
int u=Q.front();
Q.pop_front();
for(int i = head[u];i != -1;i = edg[i].next)
{
int to=edg[i].to;
if(dis2[to]>dis2[u]+edg[i].val)
{
dis2[to]=dis2[u]+edg[i].val;
if(!vis2[to])
{
vis2[to]=1;
if(!Q.empty()&&dis2[to]<dis2[Q.front()])
{
Q.push_front(to);
}
else
{
Q.push_back(to);
}
}
}
}
vis2[u]=0;
}
}
int main()
{
int n,m,rt,d1,d2;
scanf("%d%d%d%d%d",&n,&m,&rt,&d1,&d2);
init();
for(int i = 1;i <= n/*刚刚把n写成m,莫名调试发现边数不够...*/;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
spfa1(d1);
spfa2(d2);
printf("%lld\n",min(dis1[rt]+dis1[d2],dis2[rt]+dis2[d1]));
return 0;
}