superoj906 flood

題目描述

輸入格式

第一行三個數: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;
}
迪傑斯特拉+堆 有待學習

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章