題目描述
輸入格式
第一行三個數: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;
}
迪傑斯特拉+堆 有待學習