您的位置:首页 > 其它

【bzoj2763】 JLOI2011飞行路线 分层最短路

2015-08-13 14:53 267 查看
我会说这是太神给NOIP入门的同学出的题么?!表示今天刚做,虽然以前学过,但这是第一次写,要注意建边的时候只需要建一层的就可以了,然后每次跑spfa的时候,看看能不能跑到下一层。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 200010
#define inf 1000000000
#define maxm 200010

using namespace std;

int next[maxm],to[maxm],len[maxm],head[maxn];
int dis[maxn],q[maxn];
bool vis[maxn];
int n,m,T,k,s,t,num;

int cal(int x,int y)
{
	return x+y*n;
}

void addedge(int x,int y,int z)
{
	num++;to[num]=y;len[num]=z;next[num]=head[x];head[x]=num;
}

void spfa()
{
	for (int i=0;i<=cal(n,k);i++) dis[i]=inf;
	int l=0,r=1;
	dis[s]=0;q[1]=s;vis[s]=1;
	while (l!=r)
	{
		l++;if (l==maxn) l=0;
		int x=q[l];
		int d=x/n,t=x%n;
		for (int p=head[t];p;p=next[p])
		{
		  if (dis[cal(to[p],d)]>dis[cal(t,d)]+len[p])
		  {
		  	dis[cal(to[p],d)]=dis[cal(t,d)]+len[p];
		  	if (!vis[cal(to[p],d)])
		  	{
		  		vis[cal(to[p],d)]=1;
		  		r++;if (r==maxn) r=0;
		  		q[r]=cal(to[p],d);
		  	}
		  }
		  if (d<k && dis[cal(t,d)]<dis[cal(to[p],d+1)])
		  {
		  	dis[cal(to[p],d+1)]=dis[cal(t,d)];
		  	if (!vis[cal(to[p],d+1)])
		  	{
		  		vis[cal(to[p],d+1)]=1;
		  		r++;if (r==maxn) r=0;
		  		q[r]=cal(to[p],d+1);
		  	}
		  }
		}
		vis[x]=0;
	}
}

int main()
{
	scanf("%d%d%d%d%d",&n,&m,&k,&s,&t);
	for (int i=1;i<=m;i++)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		addedge(x,y,z);addedge(y,x,z);
	}
	spfa();
	printf("%d\n",dis[cal(t,k)]);
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: