第一行三个数:N,M,K ,分别代表景点数、路径数、拥有下水道口的景点数。
第二行有 K 个数,每一个数表示该景点拥有一个下水道口。
接下来 M 行,每行三个数:u,v,w ,表示存在一条从 u 到 v 的双向路,水流过这条路需要 w 的时间。
题目描述
输入格式
输出格式
输出一行 N 个数,分别表示该景点被水淹没的最早时间。
拥有下水道口的景点你可以认为淹没的最早时间为 0 。
样例数据 1
分析:
设置超级原点,在超级原点和有下水道的点间连len=0的边,跑最短路
此题卡spfa, 要用迪杰斯特拉+堆
我用的spfa TLE
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int dis[200001];
struct node
{
int len;
int to;
int next;
};
node bian[400001];
int first[200001];
int n,m,size,k;
int p[30000001];
bool exist[200001];
inline void inser(int a,int b,int c)
{
size++;
bian[size].to=b;
bian[size].len=c;
bian[size].next=first[a];
first[a]=size;
}
inline int read()
{
int k=0,f=1;
char c=getchar();
while(c>'9'||c<'0') {c=getchar();}
while(c>='0'&&c<='9') {k=(k<<3)+(k<<1)+(c-'0'); c=getchar();}
return k*f;
}
int main()
{
// freopen("flood.in","r",stdin);
//freopen("flood.out","w",stdout);
n=read();
m=read();
k=read();
int i,j,s,t,u;
int a,b,c;
int head=0;
int tail=0;
memset(dis,127,sizeof(dis));
for(i=1;i<=k;i++)
{
s=read();
p[++tail]=s;
dis[s]=0;
exist[s]=1;
}
for(i=1;i<=m;i++)
{
a=read();
b=read();
c=read();
inser(a,b,c);
inser(b,a,c);
}
while(head^tail)
{
head++;
u=p[head];
exist[u]=0;
for(i=first[u];i;i=bian[i].next)
{
t=bian[i].to;
if(dis[t]>dis[u]+bian[i].len)
{
dis[t]=dis[u]+bian[i].len;
if(!exist[t])
{
exist[t]=1;
p[++tail]=t;
}
}
}
}
for(i=1;i<=n;i++) cout<<dis[i]<<" ";
return 0;
}
迪杰斯特拉+堆 有待学习