1. 程式人生 > >11-1 noip模擬 第二題 SPFA+狀壓dp

11-1 noip模擬 第二題 SPFA+狀壓dp

#include 
#include
#include
#include

using namespace std;

struct edge{
	long long y,l,z;
}f[50010*2];

long long i,j,g[10010],n,m,k,t,dis[17][10010],T,d[16],as,at;
bool v[10010];
long long S,F[20][140000];
void spfa(long long st,long long it){
	long long i,j,k,l,r,q[100100];
	l=0;r=1;
	q[r]=st;
	memset(dis[it],78,sizeof dis[it]);
	memset(v,0,sizeof v);
	dis[it][st]=0;
	while(l!=r){
		l++;
		if(l==100000)l=1;
		k=g[q[l]];
		while(k){
			if(dis[it][f[k].y]>dis[it][q[l]]+f[k].z){
				dis[it][f[k].y]=dis[it][q[l]]+f[k].z;
				if(v[f[k].y]==0){
					v[f[k].y]=1;
					r++;
					if(r==100000)r=1;
					q[r]=f[k].y;
				}
			}
			k=f[k].l;
		}
		v[q[l]]=0;
	}
}

long long count(long long k){
	long long u=k,i=0;
	while(u){
		i+=u%2;
		u/=2;
	}
	return i;
}

int  main(){
	scanf("%lld%lld%lld%lld",&n,&m,&k,&t);
	for(i=1;i<=m;i++){
		long long x,y,w;
		scanf("%lld%lld%lld",&x,&y,&w);
		f[++T].y=y;
		f[T].l=g[x];
		g[x]=T;
		f[T].z=w;
		f[++T].y=x;
		f[T].l=g[y];
		g[y]=T;
		f[T].z=w;
	}
	for(i=1;i<=k;i++){
		long long _k;
		scanf("%lld",&_k);
		spfa(_k,i);
		d[i]=_k;
	}
	spfa(1,0);spfa(n,k+1);
	memset(v,0,sizeof v);
	as=-1;at=(long long)2100000000*5;d[0]=1;d[k+1]=n;

	memset(F,255,sizeof F);
	for(i=1;i<=k+1;i++){
		F[i][ (1 << ( (i+1) -1))+1]= dis[0][d[i]]; 
	}
	F[0][1]=0;
	for(S=1;S<=(1 << 17)-1;S++){
		for(i=0;i<=k+1;i++){
			if(( ( S >> (i+1-1) )& 1 )== 1){
				for(j=0;j<=k+1;j++){
					if(j!=i && ((S >> j) & 1 ==1 )&&F[j][S- (1 << i)]!=-1){
						if(F[i][S]==-1||F[i][S]>F[j][S- (1 << i)]+dis[j][d[i]])F[i][S]=F[j][S- (1 << i)]+dis[j][d[i]];
					}
				}
			}
		}
	}
	as=-1;
	for(S=(1 <<( k+1 )); S<=(1<<17)-1;S++)
		if((S >> (k+1) )& 1==1&& S % 2 == 1 ){
			long long y=count(S);
			y-=2;
			if(y>=as){
				j=(long long)2100000000*5;
				for(i=1;i<=k+1;i++){
					if(F[i][S]!=-1)j=min(j,F[i][S]+dis[i][d[0]]);
				}
				if(j<=t){
					if(y==as)at=min(j,at);else
						at=j;
					as=y;
				}
			}		
		}
	if(as==-1)printf("-1");else printf("%lld %lld",as,at);
	return 0;	
}