bzoj1097 [POI2007]旅游景点atr(spfa+状压dp)
2018-01-25 22:43
260 查看
首先spfa预处理一下K个点以及起终点之间的最小距离。
然后比较显然的状压dp。f[S][i]表示走过了状态为S的点,现在在i的最短路。枚举一个j去转移,判断一下合法就好了。复杂度看上去是O(km+2kk2)的。
tips:又被&的优先级低坑了…下次一定要长记性qaq
还要特判k=0的情况,wa成狗的真相。
mp数组没开到n却还用了n的蒟蒻我。
然后比较显然的状压dp。f[S][i]表示走过了状态为S的点,现在在i的最短路。枚举一个j去转移,判断一下合法就好了。复杂度看上去是O(km+2kk2)的。
tips:又被&的优先级低坑了…下次一定要长记性qaq
还要特判k=0的情况,wa成狗的真相。
mp数组没开到n却还用了n的蒟蒻我。
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define N 20010 #define M 200010 inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int n,m,K,h ,num=0,dis ,f[1100000][22],bin[22],bf[22],mp[22][22]; bool inq ; struct edge{ int to,next,val; }data[M<<1]; inline void spfa(int S){ deque<int>q;memset(dis,inf,sizeof(dis)); dis[S]=0;q.push_back(S);inq[S]=1; while(!q.empty()){ int x=q.front();q.pop_front();inq[x]=0; for(int i=h[x];i;i=data[i].next){ int y=data[i].to; if(dis[y]>dis[x]+data[i].val){ dis[y]=dis[x]+data[i].val; if(!inq[y]){ if(!q.empty()&&dis[q.front()]>dis[y]) q.push_front(y); else q.push_back(y);inq[y]=1; } } } }if(S==n) S=0; for(int i=2;i<=K+1;++i) mp[S][i]=dis[i]; } inline int spfa1(){ deque<int>q;memset(dis,inf,sizeof(dis)); dis[1]=0;q.push_back(1);inq[1]=1; while(!q.empty()){ int x=q.front();q.pop_front();inq[x]=0; for(int i=h[x];i;i=data[i].next){ int y=data[i].to; if(dis[y]>dis[x]+data[i].val){ dis[y]=dis[x]+data[i].val; if(!inq[y]){ if(!q.empty()&&dis[q.front()]>dis[y]) q.push_front(y); else q.push_back(y);inq[y]=1; } } } }return dis ; } int main(){ // freopen("a.in","r",stdin); n=read();m=read();K=read();bin[0]=1; for(int i=1;i<=K;++i) bin[i]=bin[i-1]<<1;int tot=bin[K]-1; for(int i=1;i<=m;++i){ int x=read(),y=read(),val=read(); data[++num].to=y;data[num].next=h[x];h[x]=num;data[num].val=val; data[++num].to=x;data[num].next=h[y];h[y]=num;data[num].val=val; }int owo=read(); while(owo--){ int x=read(),y=read();bf[y]|=bin[x-2]; }if(K==0){printf("%d\n",spfa1());return 0;}//特判直接1~n的最短路 for(int i=1;i<=K+1;++i) spfa(i);spfa(n);memset(f,inf,sizeof(f)); for(int i=1;i<=K;++i) if(!bf[i+1]) f[bin[i-1]][i]=mp[1][i+1]; for(int S=1;S<=tot;++S) for(int i=1;i<=K;++i){ if(f[S][i]==inf) continue; for(int j=1;j<=K;++j){ if(S&bin[j-1]||(bf[j+1]&S)!=bf[j+1]) continue; f[S|bin[j-1]][j]=min(f[S|bin[j-1]][j],f[S][i]+mp[i+1][j+1]); } }int ans=inf; for(int i=1;i<=K;++i) ans=min(ans,f[tot][i]+mp[0][i+1]); printf("%d\n",ans); return 0; }
相关文章推荐
- 【BZOJ】1097: [POI2007]旅游景点atr(spfa+状压dp)
- bzoj1097: [POI2007]旅游景点atr[最短路预处理+状压dp]
- 1097: [POI2007]旅游景点atr dijkstra+状压dp
- 【BJOJ1097】旅游景点 atr (spfa+状压dp)
- 【BZOJ1097】[POI2007]旅游景点atr 最短路+状压DP
- BZOJ1097 [POI2007]旅游景点atr
- bzoj 1097: [POI2007]旅游景点atr(状压DP)
- BZOJ1097: [POI2007]旅游景点atr
- [BZOJ1097][POI2007]旅游景点atr(状压dp)
- BZOJ1097: [POI2007]旅游景点atr
- BZOJ1097: [POI2007]旅游景点atr
- BZOJ_1097_[POI2007]旅游景点atr_状压DP
- bzoj 1097 [POI2007]旅游景点atr(最短路,状压DP)
- [BZOJ1097][POI2007]旅游景点atr(状压dp)
- BZOJ 1097: [POI2007]旅游景点atr [DP 状压 最短路]
- 【bzoj1097】[POI2007]旅游景点atr 状压dp+堆优化Dijkstra
- BZOJ 1097: [POI2007]旅游景点atr( 最短路 + 状压dp )
- BZOJ 1097: [POI2007]旅游景点atr 状压,预处理,最短路
- BZOJ 1097 [POI2007]旅游景点atr
- BZOJ1097 [POI2007]旅游景点atr