[POI2009]Wie

题目

BZOJ
虽然是解压题但也学到了简洁的码风

做法

(dijkstra)跑动规

My complete code

#include<bits/stdc++.h>
#include<vector>
#include<queue>
using namespace std;
typedef int LL;
const LL maxn=1e6+9,inf=0x3f3f3f3f,up=1<<14;
inline LL Read(){
	LL x(0),f(1); char c=getchar();
	while(c<'0' || c>'9'){ if(c=='-') f=-1; c=getchar(); }
	while(c>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0', c=getchar();
	return x*f;
}
struct node{
	LL to,nxt,d,bit;
}dis[maxn];
LL n,num,m,p,k;
LL head[209],lu[209][up],s[209];
bool visit[209][up];
inline void Add(LL u,LL v,LL t,LL bit){
	dis[++num]=(node){v,head[u],t,bit}; head[u]=num;
}
#define mpr(x,y,z) make_pair(make_pair(x,y),z)
typedef pair<LL,LL> pii;
priority_queue<pair<pii,LL>,vector<pair<pii,LL> >,greater<pair<pii,LL> > >que;
inline LL Dij(){
	memset(visit,false,sizeof(visit));
	memset(lu,inf,sizeof(lu));
	lu[1][0]=0;
	que.push(mpr(0,1,0));
	while(que.size()){
		LL d(que.top().first.first), u(que.top().first.second), bit(que.top().second);
		que.pop();
		if(visit[u][bit]) continue;
		visit[u][bit]=true; 
		if(u==n) return d;
		bit|=s[u];
		for(LL i=head[u];i;i=dis[i].nxt){
			LL v(dis[i].to);
			if((bit|dis[i].bit)!=bit) continue;
			if(lu[v][bit]>d+dis[i].d){
				lu[v][bit]=d+dis[i].d;
				que.push(mpr(lu[v][bit],v,bit));
			}
		}
	}return -1;
}
int main(){
	n=Read(); m=Read(); p=Read(); k=Read();
	for(LL i=1;i<=k;++i){
		LL u(Read()),tot(Read());
		while(tot--){
			LL x(Read());
			s[u]|=(1<<x-1);
		}
	}
	while(m--){
		LL u(Read()),v(Read()),t(Read()),tot(Read());
		LL bit(0);
		while(tot--){
			LL x(Read());
			bit|=(1<<x-1);
		}
		Add(u,v,t,bit); Add(v,u,t,bit);
	}
	printf("%d",Dij());
	return 0;
}
原文地址:https://www.cnblogs.com/y2823774827y/p/10490231.html