bzoj1097: [POI2007]旅游景点atr[最短路预处理+状压dp]
2014-09-30 13:17
519 查看
某位厉害的学长告诉我,多做POI,于是乎:poi计划开始。
既然经过不算停留,那么就自由地spfa预处理吧
每一个点都有自己的依赖点。
由于并不是对应的依赖关系没办法得到拓扑序(甚至压根就没有),树形DP算了吧。
再看看k的范围这么小,是不是可以状态压缩呢?
那么可以得到一个DP转移方程:
之前预处理得到d[i][j]为点i到点j处理出的最短路
f[p][opt]=min{f[to][opt|(1<<(to-1))]+d[p][to]}(不用考虑是否有边相连,因为如果没边,d[p][to]就是INF)
拓扑序不明显,循环比较难弄,那就记忆化搜索吧。反正状压万年都是这样写。
-------------------------------------------------------------------------------------------------------------------------------------------------
Code:
既然经过不算停留,那么就自由地spfa预处理吧
每一个点都有自己的依赖点。
由于并不是对应的依赖关系没办法得到拓扑序(甚至压根就没有),树形DP算了吧。
再看看k的范围这么小,是不是可以状态压缩呢?
那么可以得到一个DP转移方程:
之前预处理得到d[i][j]为点i到点j处理出的最短路
f[p][opt]=min{f[to][opt|(1<<(to-1))]+d[p][to]}(不用考虑是否有边相连,因为如果没边,d[p][to]就是INF)
拓扑序不明显,循环比较难弄,那就记忆化搜索吧。反正状压万年都是这样写。
-------------------------------------------------------------------------------------------------------------------------------------------------
Code:
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #define For(i,l,r) for(int (i)=(l);(i)<=(r);(i)++) using namespace std; const int N=30010,M=500010; int INF; struct list{ int p,val; list *next; list(){} inline list* Set(int _p,int _val,list* _next){ p=_p; val=_val; next=_next; return this; } }T[M],*head ;int data=0; struct node{ int w,u; bool operator<(const node &b)const{ return w>b.w; } };priority_queue <node> Q; int dis ,d[30][30],dp[21][1<<20]; int n,m,k,dep[30]; void Addedge(int u,int v,int c){ head[u]=(T+(data++))->Set(v,c,head[u]); head[v]=(T+(data++))->Set(u,c,head[v]); } void spfa(int s){ memset(dis,127,sizeof(dis)); INF=dis[0]; dis[s]=0; Q.push((node){0,s}); while(!Q.empty()){ int u=Q.top().u; Q.pop(); for(list *t=head[u];t;t=t->next) if(dis[t->p]>dis[u]+t->val){ dis[t->p]=dis[u]+t->val; Q.push((node){dis[t->p],t->p}); } } } int dfs(int p,int opt){ if(dp[p][opt]>=0) return dp[p][opt]; if(opt==(1<<k)-1) return d[p][k+1]; dp[p][opt]=~0U>>3; for(int i=1;i<=k;i++) if((opt&dep[i-1])==dep[i-1]) dp[p][opt]=min(dp[p][opt],dfs(i,opt|(1<<(i-1)))+d[p][i]); return dp[p][opt]; } int main(){ freopen("1097.in","r",stdin); int x,y,z; scanf("%d%d%d",&n,&m,&k); For(i,1,m){ scanf("%d%d%d",&x,&y,&z); x--; y--; Addedge(x,y,z); }scanf("%d",&x); while(x--){ scanf("%d%d",&y,&z); y-=2; z-=2; dep[z]|=(1<<y); } For(i,0,k){ spfa(i); For(j,0,k) d[i][j]=dis[j]; d[i][k+1]=dis[n-1]; }memset(dp,-1,sizeof(dp)); printf("%d\n",dfs(0,0)); return 0; }
相关文章推荐
- bzoj1097 [POI2007]旅游景点atr(spfa+状压dp)
- 【BZOJ1097】[POI2007]旅游景点atr 最短路+状压DP
- 1097: [POI2007]旅游景点atr dijkstra+状压dp
- bzoj 1097 [POI2007]旅游景点atr(最短路,状压DP)
- BZOJ 1097: [POI2007]旅游景点atr( 最短路 + 状压dp )
- 【BZOJ】1097: [POI2007]旅游景点atr(spfa+状压dp)
- BZOJ 1097: [POI2007]旅游景点atr [DP 状压 最短路]
- BZOJ 1097: [POI2007]旅游景点atr 状压,预处理,最短路
- BZOJ1097: [POI2007]旅游景点atr
- 【BJOJ1097】旅游景点 atr (spfa+状压dp)
- BZOJ1097: [POI2007]旅游景点atr
- [BZOJ1097][POI2007]旅游景点atr(状压dp)
- [BZOJ1097][POI2007]旅游景点atr(状压dp)
- 【bzoj1097】[POI2007]旅游景点atr 状压dp+堆优化Dijkstra
- 【BZOJ1097】[POI2007]旅游景点atr【最短路】【状压DP】【记忆化搜索】
- BZOJ 1097: [POI2007]旅游景点atr 最短路 堆优Dijkstra 状压
- bzoj 1097: [POI2007]旅游景点atr(状压DP)
- BZOJ1097 [POI2007]旅游景点atr
- [bzoj1097][POI2007]旅游景点atr【最短路】【状压dp】
- BZOJ_1097_[POI2007]旅游景点atr_状压DP