您的位置:首页 > 编程语言

superoj906 flood

2015-10-08 18:30 162 查看
题目描述


输入格式

第一行三个数:N,M,K ,分别代表景点数、路径数、拥有下水道口的景点数。

第二行有 K 个数,每一个数表示该景点拥有一个下水道口。

接下来 M 行,每行三个数:u,v,w ,表示存在一条从 u 到 v 的双向路,水流过这条路需要 w 的时间。


输出格式

输出一行 N 个数,分别表示该景点被水淹没的最早时间。

拥有下水道口的景点你可以认为淹没的最早时间为 0 。


样例数据 1

输入  [复制]

3 2 2 

1 2 

1 3 2 

2 3 3
输出

0 0 2

对于 100% 的数据:1≤N, M≤100000; 0≤ti≤1000;0<w≤1000 。

分析:

       设置超级原点,在超级原点和有下水道的点间连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;
}
迪杰斯特拉+堆 有待学习
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  代码 算法