CSU 1843:Jumping monkey 状压BFS (2010 Southwestern European Regional Contest)
2017-03-28 16:48
1456 查看
1843: Jumping monkey
Submit Page
Summary
Time Limit: 1 Sec
Memory Limit: 128 Mb
Submitted: 71
Solved: 13
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).
); 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).
, 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).
之前说过了,在第四次多校赛的时候A了一道状压bfs,其实我当时就联想到了这题。这题是第三次多校赛的题,当时是把这题扔给队友去补了,自己就只是看了一下思路。后来发现状压很有用,还是好好补补为好,而且第四次的题比较简单,就来填之前的坑了。
说实话,这个题的题面在上个学期万伟老师好像在我们程设课上提过,然而当时并没有细说我也没有深究,没想到考到了。也并没有想到用状压。但是现在一看到这样的数据范围就会首先去想状压了。
首先,如果给出的图并非一棵树,即存在环,显然不可能使得猴子无路可走。当是一棵树的时候,我们用对应位置的0和1分别表示当前位置是否可能存在猴子。初始状态当然每个点都为1。转移的时候,枚举任意一个可以开枪打的点(当然选可能存在猴子的点),然后再模拟打完之后每个点猴子可能的移动到的位置。在这里,我们设置一个nxt数组,如果存在边(u,v),那么nxt[u]|=(1<<v),nxt[v]|=(1<<u)。如此,nxt[i]就保存了从i点出发,猴子所有可能移动的情况。我们利用bfs不断的拓展状态、一步步的转移,并且同时记录打枪的路径,直到出现一个所有位置都为0的状态,即所有位置都不可能有猴子,说明猴子已经无路可走。当然了,要设置v数组判断状态是否重复出现。
另外,此题的时间限制还是比较死的,只有1s的时间,时间复杂度是O(n^2*2^n),稍不注意常数可能就会超时。下面是代码(好像状压的代码都很短?):
Submit Page
Summary
Time Limit: 1 Sec
Memory Limit: 128 Mb
Submitted: 71
Solved: 13
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; yourbullets 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 formatL: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 Input
2 1 0 1 3 3 0 1 1 2 2 0 4 3 0 1 2 3 1 3 0 0
Sample Output
2: 0 0 Impossible 4: 1 3 3 1
之前说过了,在第四次多校赛的时候A了一道状压bfs,其实我当时就联想到了这题。这题是第三次多校赛的题,当时是把这题扔给队友去补了,自己就只是看了一下思路。后来发现状压很有用,还是好好补补为好,而且第四次的题比较简单,就来填之前的坑了。
说实话,这个题的题面在上个学期万伟老师好像在我们程设课上提过,然而当时并没有细说我也没有深究,没想到考到了。也并没有想到用状压。但是现在一看到这样的数据范围就会首先去想状压了。
首先,如果给出的图并非一棵树,即存在环,显然不可能使得猴子无路可走。当是一棵树的时候,我们用对应位置的0和1分别表示当前位置是否可能存在猴子。初始状态当然每个点都为1。转移的时候,枚举任意一个可以开枪打的点(当然选可能存在猴子的点),然后再模拟打完之后每个点猴子可能的移动到的位置。在这里,我们设置一个nxt数组,如果存在边(u,v),那么nxt[u]|=(1<<v),nxt[v]|=(1<<u)。如此,nxt[i]就保存了从i点出发,猴子所有可能移动的情况。我们利用bfs不断的拓展状态、一步步的转移,并且同时记录打枪的路径,直到出现一个所有位置都为0的状态,即所有位置都不可能有猴子,说明猴子已经无路可走。当然了,要设置v数组判断状态是否重复出现。
另外,此题的时间限制还是比较死的,只有1s的时间,时间复杂度是O(n^2*2^n),稍不注意常数可能就会超时。下面是代码(好像状压的代码都很短?):
#include <bits/stdc++.h> using namespace std; deque<i 10e39 nt> que,ans; int num[1<<21],fa[1<<21]; int n,m,nxt[21]; bool v[1<<21]; int main() { while(~scanf("%d%d",&n,&m) && n) { bool flag=0; int l=1<<n; for(int i=0;i<l;i++) v[i]=fa[i]=0; memset(nxt,0,sizeof(nxt)); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); nxt[u]|=(1<<v); nxt[v]|=(1<<u); } if (m>n-1) { puts("Impossible"); continue; } v[(1<<n)-1]=1; que.clear(); que.push_back((1<<n)-1); while (!que.empty() && !flag) { int cur=que.front(); que.pop_front(); for(int i=0;i<n;i++) { int next=0; if (cur&(1<<i)) { for(int j=0;j<n;j++) if ((cur&(1<<j)) && j!=i) next|=nxt[j]; if (!v[next]) { v[next]=1; num[next]=i; fa[next]=cur; que.push_back(next); if (!next) {flag=1;break;} } } } } if (flag) { ans.clear(); for(int cur=0;fa[cur];cur=fa[cur]) ans.push_back(num[cur]); printf("%d: ",ans.size()); for(int i=ans.size()-1;i>=0;i--) printf("%d%c",ans[i],!i? '\n':' '); } else puts("Impossible"); } return 0; }
相关文章推荐
- CSU 1848:3-sided dice 高斯消元(2010 Southwestern European Regional Contest)
- CSU 1842: Fake scoreboard dinic(2010 Southwestern European Regional Contest)
- csu 1843 Jumping monkey 状压+bfs
- CSU 1855: Shut the Box 状压BFS(2011 Mid-Central USA Regional Contest)
- ACM Southwestern European Regional Programming Contest (SWERC) 2017 F 水题
- Gym 101308(ACM ICPC 2009–2010, Northeastern European Regional Contest)
- 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) B - Bribing Eve
- ACM Southwestern European Regional Programming Contest (SWERC) 2017--Cakey McCakeFace
- 2010-2011 ACM-ICPC Northeastern European Regional Contest (NEERC 10) G - Game of 10
- 2017-2018 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2017)
- 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) E.Passwords AC自动机+dp
- 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
- 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) D.Dinner Bet 概率DP+排列组合
- 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
- Southeastern European Regional Programming Contest 2010 D Problemsetting
- ACM Southwestern European Regional Programming Contest (SWERC) 2017 J 智商题(模m同余)
- 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016) F dfs序+树状数组
- hdu 3756 || Dome of Circus || 2010 Northeastern European Regional Contest(三分)
- ACM Southwestern European Regional Programming Contest (SWERC) 2017 A map+暴力
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem H. Hometask 水题