BZOJ1975 [Sdoi2010]魔法猪学院 k短路

欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ1975


题意概括

  给出一个无向图,让你走不同的路径,从1到n,路径长度之和不超过E,求最大路径条数。


题解

  k短路模板题。


 

代码

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N=5005,M=200002;
const double Inf=1e300;
struct Gragh{
	int cnt,y[M*2],nxt[M*2],fst[N],vis[N],q[N],n;
	double z[M*2],dis[N];
	void clear(int n_){
		cnt=0,n=n_;
		memset(fst,0,sizeof fst);
	}
	void add(int a,int b,double c){
		y[++cnt]=b,z[cnt]=c,nxt[cnt]=fst[a],fst[a]=cnt;
	}
	void spfa(int st){
		int X,Y,head=0,tail=0,qmod=N-3;
		for (int i=1;i<=n;i++)
			dis[i]=Inf;
		memset(vis,0,sizeof vis);
		dis[st]=0,vis[q[tail=tail%qmod+1]=st]=1;
		while (head!=tail){
			vis[X=q[head=head%qmod+1]]=0;
			for (int i=fst[X];i;i=nxt[i])
				if (dis[X]+z[i]<dis[Y=y[i]]){
					dis[Y]=dis[X]+z[i];
					if (!vis[Y])
						vis[q[tail=tail%qmod+1]=Y]=1;
				}
		}
	}
}yg,g;
const int S=2000000;
int id[S],heap_size;
double now[S];
double h(int x){return g.dis[x];}
double G(int x){return now[x]+h(id[x]);}
void heap_clear(){heap_size=0;}
bool heap_empty(){return heap_size==0;}
bool heap_cmp(int a,int b){return G(a)<G(b);}
void heap_down(){
	for (int i=1,j=i<<1;j<=heap_size;i=j,j=i<<1){
		j+=j<heap_size&&!heap_cmp(j,j+1);
		if (heap_cmp(i,j))
			break;
		swap(id[i],id[j]),swap(now[i],now[j]);
	}
}
void heap_up(){
	for (int i=heap_size,j=i>>1;i>1;i=j,j=i>>1)
		if (!heap_cmp(j,i))
			swap(id[i],id[j]),swap(now[i],now[j]);
		else
			break;
}
void heap_pop(){
	id[1]=id[heap_size];
	now[1]=now[heap_size--];
	heap_down();
}
void heap_push(int x,double nowdis){
	id[++heap_size]=x;
	now[heap_size]=nowdis;
	heap_up();
}
int n,m;
double E;
int solve(){
	int ans=0;
	heap_clear();
	heap_push(1,0);
	while (!heap_empty()){
		int x=id[1];
		double nowdis=now[1];
		heap_pop();
		if (x==n){
			if (nowdis>E)
				return ans;
			E-=nowdis;
			ans++;
			continue;
		}
		for (int i=yg.fst[x];i;i=yg.nxt[i]){
			int y=yg.y[i];
			heap_push(y,nowdis+yg.z[i]);
		}
	}
}
int main(){
	scanf("%d%d%lf",&n,&m,&E);
	g.clear(n),yg.clear(n);
	for (int i=1;i<=m;i++){
		int a,b;
		double e;
		scanf("%d%d%lf",&a,&b,&e);
		yg.add(a,b,e);
		g.add(b,a,e);
	}
	g.spfa(n);
	printf("%d",solve());
	return 0;
}

  

posted @ 2017-12-19 15:52  zzd233  阅读(313)  评论(0编辑  收藏  举报