1. 程式人生 > >BZOJ 2763 [JLOI2011]飛行路線

BZOJ 2763 [JLOI2011]飛行路線

add urn turn sin clu jloi2011 pop UC const

題解:建出分層圖,跑最短路

經驗教訓:一定要檢查空間,並不都是開兩倍的m!!!!!!!!!!!!!!!!!!!!!!!!!!!

仔細檢查是否多開了一個0或少開了一個0

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxm=50009;
const int maxn=10009;
const int maxk=13;
const int oo=1000000000;

int n,m,k;
int p[11][maxn];
int totn=0;
int ans=oo;

int cntedge=0;
int head[maxn*maxk]={0};
int to[maxm*maxk*4]={0},nex[maxm*maxk*4]={0},dist[maxm*maxk*4]={0};
void Addedge(int x,int y,int z){
	nex[++cntedge]=head[x];
	to[cntedge]=y;
	dist[cntedge]=z;
	head[x]=cntedge;
}

int d[maxn*maxk];
int vis[maxn*maxk];
struct HeapNode{
	int v,mindist;
	HeapNode(int x){
		v=x;mindist=d[x];
	}
	bool operator < (const HeapNode &rhs) const{
		return mindist>rhs.mindist;
	}
};
priority_queue<HeapNode>q;

int s,t;
void Dijkstra(){
	for(int i=1;i<=totn;++i)d[i]=oo;
	d[p[0][s]]=0;q.push(HeapNode(p[0][s]));
	while(!q.empty()){
		HeapNode x=q.top();q.pop();
		int u=x.v;
		if(vis[u])continue;
		vis[u]=1;
		for(int i=head[u];i;i=nex[i]){
			if(d[u]+dist[i]<d[to[i]]){
				d[to[i]]=d[u]+dist[i];
				q.push(HeapNode(to[i]));
			}
		}
	}
}

int main(){
	scanf("%d%d%d",&n,&m,&k);
	
	for(int j=0;j<=k;++j){
		for(int i=1;i<=n;++i){
			p[j][i]=++totn;
		}
	}
	
	scanf("%d%d",&s,&t);
	++s;++t;
	while(m--){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		++x;++y;
		for(int i=0;i<=k;++i){
			Addedge(p[i][x],p[i][y],z);
			Addedge(p[i][y],p[i][x],z);
		}
		for(int i=0;i<k;++i){
			Addedge(p[i][x],p[i+1][y],0);
			Addedge(p[i][y],p[i+1][x],0);
		}
	}
	
	Dijkstra();
	for(int i=0;i<=k;++i)ans=min(ans,d[p[i][t]]);
	
	printf("%d\n",ans);
	return 0;
}

  

BZOJ 2763 [JLOI2011]飛行路線