UVALive4959Jumping monkey 【状压DP】
来源:互联网 发布:完美游戏平台网络错误 编辑:程序博客网 时间:2024/06/04 23:33
You are a hunter chasing a monkey in the forest, trying to shoot it down with your all-powerful automatic machine gun. The monkey is hiding somewhere behind the branches of one of the trees, out of your sight. You can aim at one of the trees and shoot; your bullets are capable of going through the branches and killing the monkey instantly if it happens to be in that tree. If it isn't, the monkey takes advantage of the time it takes you to reload and takes a leap into a neighbouring tree without you noticing. It never stays in the same place after a shot. You would like to find out whether there is an strategy that allows you to capture the monkey for sure, irrespective of its initial location and subsequent jumps. If so, you need to determine the shortest sequence of shots guaranteeing this. As an example, consider the situation in which there are only two neighboring trees in the forest (left hand side of Figure 2). It is then possible to make sure you capture the monkey by shooting twice at the same tree. Your first shot succeeds if the monkey happened to be there in the rst place. Otherwise, the monkey was behind the other tree and it will necessarily have moved when you shoot for the second time. However, depending on the shape of the forest it may not possible for you to ensure victory. One example of this is if there are three trees, all connected to one another (right hand side of Figure 2). No matter where you aim at, there are always two possible locations for the monkey at any given moment. (Note that here we are concerned with the worst-case scenario where the monkey may consistently guess your next target tree).Input The input consists of several test cases, separated by single blank lines. Each test case begins with a line containing two integers n and m ( 1≤n≤211≤n≤21 ); n is the number of trees in the forest, and m is the number of adjacency relations between trees. Each of the following m lines contains two distinct integers between 0 and n-1(inclusive), the identifiers of the trees in an adjacent pair. The order of both trees within a pair carries no meaning, and no pair appears more than once. You may further assume that no tree is adjacent to itself, and there is always a path between any two trees in the forest. The test cases will finish with a line containing only two zeros (also preceded with a blank line).Output Print a line for each test case. The line should contain the single word Impossible if the task is impossible. Otherwise, it must contain the shortest sequence of shots with the required property, in the format L:V1V2…VLL:V1V2…VL , where LL is the length of the sequence, and V1,V2,…,VLV1,V2,…,VL are space-separated integers containing the identifiers of the trees to shoot at in the right order. If several shortest sequences exist, print the lexicographically smallest one. (A sequence is smaller than another in lexicographic order if the first element on which they differ is smaller in the first one).Sample Input2 10 13 30 11 22 04 30 12 31 30 0Sample Output2: 0 0Impossible4: 1 3 3 1HintSource2010 Southwestern European Regional Contest
n很小 明显可以状态压缩dp
状态i: i&(1<<j)==1 表示:猴子可能在j位置d[i]=min(d[i],d[s]+1) | s为i状态下 在猴子可能的位置打一枪 猴子可能转移到的位置状态d[0]=0
参考大神代码 避免处理无用状态 从(1<<n)-1
状态开始 用一个队列维护可能到达的状态(到达0状态时 打死猴子)
#include<iostream>#include<cstdlib>#include<cstdio>#include<string>#include<vector>#include<deque>#include<queue>#include<algorithm>#include<set>#include<map>#include<stack>#include<ctime>#include <string.h>#include<math.h>#define pii pair<int,int>using namespace std;#define ll long longconst int inf=1e9+7;const double EPS=1e-8;int state[21];void initState(){ state[0]=1; for(int i=1;i<21;++i){ state[i]=state[i-1]<<1; }}int d[1<<21];int toIdx[21];//猴子在i位置能转移到j 则toIdx[i]&(1<<j)==1int getNextIdx(int s){//s状态下 猴子能转移到的位置 int u=0; int newS=0; while(s){ if(s&1){ newS|=toIdx[u]; } s>>=1; u+=1; } return newS;}pii pre[1<<21];int dp(int n){ int end=1<<n; fill(d,d+end,inf); fill(pre,pre+end,make_pair(-1,-1)); deque<int>que; que.push_back(end-1); while(!que.empty()){ int u=que.front(); que.pop_front(); for(int i=0;i<n;++i){ if(state[i]&u){//在i位置打一枪 int v=u^state[i];//打一枪后 猴子不在i v=getNextIdx(v);//猴子转移到v状态 if(pre[v].first==-1){ pre[v].first=u; pre[v].second=i; que.push_back(v); } if(v==0){ return 1; } } } } return 0;}void getPath(vector<int>&vec,int n){ vec.clear(); int end=1<<n; end-=1; int st=0; while(pre[st].first!=end){ vec.push_back(pre[st].second); st=pre[st].first; } vec.push_back(pre[st].second);}int main(){ //freopen("/home/lu/Documents/r.txt","r",stdin); initState(); int n,m; while(scanf("%d%d",&n,&m),n+m){ fill(toIdx,toIdx+n,0); for(int i=0;i<m;++i){ int u,v; scanf("%d%d",&u,&v); toIdx[u]|=1<<v; toIdx[v]|=1<<u; } int ans=dp(n); if(ans==0){ puts("Impossible"); } else{ vector<int>path; getPath(path,n); printf("%d:",path.size()); for(int i=path.size()-1;i>=0;--i){ printf(" %d",path[i]); } putchar('\n'); } } return 0;}
0 0
- UVALive4959Jumping monkey 【状压DP】
- NEFU642:monkey(DP)
- Monkey and Banana dp
- Monkey and Banana(dp)
- HDU1069(Monkey and Banana)DP
- hdoj1069 Monkey and Banana (dp)
- NEFU 642 Monkey(DP)
- HDU1069 Monkey and Banana 【DP】
- 【DP】 HDOJ 3506 Monkey Party
- HDOJ1069-Monkey and Banana(DP)
- HDOJ1069 Monkey and Banana【dp】
- hdu1069 Monkey and Banana--DP
- 1004 - Monkey Banana Problem (dp)
- Monkey and Banana(DP)
- HDU1069-Monkey and Banana(dp)
- hdu1069 Monkey and Banana dp
- hdoj1069 Monkey and Banana(DP)
- zoj 1093 dp Monkey and Banana
- 大话设计模式-第一章 简单工厂模式
- Android中自定义ScrollView的滑动监听事件,并在滑动时渐变标题栏背景颜色
- 接口层在重构中的作用
- Dlib+VS2017配置
- 《ACM程序设计》书中题目 X
- UVALive4959Jumping monkey 【状压DP】
- 二项分布和Beta分布
- leetcode:67. Add Binary
- SpringView
- 历届试题 回文数字
- java基础
- 命令行参数:关于java程序中main函数的String[] args参数的用法
- 关于java io知识的初步了解
- PHP服务器 支付宝 对接出现 【交易订单处理失败 请稍后再试 ALI38173】