D(1843): Jumping monkey
来源:互联网 发布:淘宝装修图片如何制作 编辑:程序博客网 时间:2024/05/16 04:45
Description
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 (
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
Sample Input
2 10 13 30 11 22 04 30 12 31 30 0
Sample Output
2: 0 0Impossible4: 1 3 3 1
Hint
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.
在保证射击成功的前提下,找一个最短的射击序列(不管猴子的初始位置和随后跳跃的位置)(同等长度输出字典序最小的)
思路:(看了大佬们的题解)
状压+最短路
1.点数n只有21明显可以状压。用状态st表示当前猴子可能的位置,初始状态为(1<<n)-1。很明显,必然打中的状态就是1<<k(1<=k<=n)的时候,猴子死亡的情况也就可 以表示为状态0.
2.考虑每一次攻击,每次攻击的点肯定是那些当前可能有猴子存在的点,再考虑每次攻击状态的转移:对于状态st,攻击的位置i,则i位置置0,而其它为1的位置清零后,其邻 接位置置1
3.所以问题就转化为由状态(1<<n)-1到0的最短路径
4.为了同时保证字典序最小,可以在每次枚举攻击位置的时候从小到大枚举
#include<iostream>#include<vector>#include<queue>using namespace std;const int N=22;const int Max=1<<N;int vis[Max],pre[Max],shoot[Max];int n,m;vector<int> ans,p[N];bool bfs(int sum){vis[sum]=1;queue<int> q;q.push(sum);while(!q.empty()){int st=q.front();q.pop();if(!st) return true;for(int i=0;i<n;i++){int next=0;for(int j=0;j<n;j++)if(i!=j&&(st&(1<<j)))for(int k=0;k<p[j].size();k++)next|=(1<<p[j][k]);if(vis[next]) continue;vis[next]=1;pre[next]=st;shoot[next]=i;q.push(next);}}return false;}int main(){while(cin>>n>>m,n+m){int sum=(1<<n)-1;for(int i=0;i<=sum;i++) vis[i]=0;for(int i=0;i<n;i++) p[i].clear();for(int a,b,i=0;i<m;i++){cin>>a>>b;p[a].push_back(b);p[b].push_back(a); } if(bfs(sum)){ans.clear();int now=0;while(now!=sum){ans.push_back(shoot[now]);now=pre[now];}cout<<ans.size()<<":";for(int i=ans.size()-1;i>=0;i--) cout<<" "<<ans[i];}else cout<<"Impossible";cout<<endl;}}
- D(1843): Jumping monkey
- CSUOJ 1843 Jumping Monkey BFS,状态压缩
- UVALive 4959 Jumping monkey
- 文章标题 CSU 1843: Jumping monkey (状态压缩+dp)
- CF D. Fox And Jumping
- Gym 101617D Jumping Haybales
- monkey.D.luffy
- Codeforces Round #290 D. Fox And Jumping
- Fox And Jumping - CodeForces 510 D
- 510D Fox And Jumping(dp+gcd)
- codeforces 510D Fox And Jumping
- codeforces 510D Fox And Jumping
- codeforces 510D Fox and Jumping
- codefoces--510D. Fox And Jumping
- #290 (div.2) D. Fox And Jumping
- codeforces 199D Jumping on Walls
- codeforces 510D D. Fox And Jumping(dp+数论)
- codeforces 510D D. Fox And Jumping(dp+数论)
- javaMail使用qq邮箱报错: 530 Error: A secure connection is requiered(such as ssl)
- 通用类型转换(template)
- POJ 1988 Cube Stacking (带权并查集+总结)
- linux进程控制总结一
- Python学习资源汇总
- D(1843): Jumping monkey
- 一维数组的查找算法
- 扩展SpringMVC以支持更精准的数据绑定1
- Linux Input输入驱动架构记录
- 参加了一个比赛
- PAT1013. 数素数 (20)
- Mybatis
- 爬虫-根据公司名抓取相关员工的linkedin数据
- AOP 动态代理