UVA12569-Planning mobile robot on Tree (EASY Version)(BFS+状态压缩)

Problem UVA12569-Planning mobile robot on Tree (EASY Version)

Accept:138  Submit:686

Time Limit: 3000 mSec

 Problem Description

 Input

The first line contains the number of test cases T (T ≤ 340). Each test case begins with four integers n, m, s, t (4 ≤ n ≤ 15, 0 ≤ m ≤ n?2, 1 ≤ s,t ≤ n, s ?= t), the number of vertices, the number of obstacles and the label of the source and target. Vertices are numbered 1 to n. The next line contains m different integers not equal to s, the vertices containing obstacles. Each of the next n ? 1 lines contains two integers u and v (1 ≤ u < v ≤ n), that means there is an edge u?v in the tree.

 Output

For each test case, print the minimum number of moves k in the first line. Each of the next k lines containstwointegers a and b,thatmeanstomovetherobot/obstaclefrom a to b. Ifthereisnosolution, print ‘-1’. If there are multiple solutions, any will do. Print a blank line after each test case.

 Sample Input

3
4 1 1 3
2
1 2
2 3
2 4
6 2 1 4
2 3
1 2
2 3
3 4
2 5
2 6
8 3 1 5
2 3 4
1 2
2 3
3 4
4 5
1 6
1 7
2 8

 Sample Ouput

Case 1: 3
2 4
1 2
2 3

Case 2: 6
2 6
3 2
2 5
1 2
2 3
3 4

Case 3: 16
1 7
2 1
1 6
7 1
1 2
2 8
3 2
2 1
1 7
4 3
3 2
2 1
8 2
2 3
3 4
4 5

题解:看到n的范围状压是比较正的思路,二进制储存,BFS搜索,vis数组稍微有一点改动,其中一维记录石头,再有一维记录机器人。水题。

  1 #include <bits/stdc++.h>
  2
  3 using namespace std;
  4
  5 const int maxn = 16;
  6 int n, m, s, t;
  7 int ori;
  8
  9 struct Edge {
 10     int to, next;
 11 }edge[maxn << 1];
 12
 13 struct Node {
 14     int sit, robot;
 15     int time;
 16     Node(int sit = 0, int robot = 0, int time = 0) :
 17         sit(sit), robot(robot), time(time) {}
 18 };
 19
 20 int tot, head[maxn];
 21 pair<int,int> pre[40000][maxn];
 22 bool vis[40000][maxn];
 23
 24 void init() {
 25     tot = 1;
 26     memset(head, -1, sizeof(head));
 27     memset(pre, -1, sizeof(pre));
 28     memset(vis, false, sizeof(vis));
 29 }
 30
 31 void AddEdge(int u, int v) {
 32     edge[tot].to = v;
 33     edge[tot].next = head[u];
 34     head[u] = tot++;
 35 }
 36
 37 inline int get_pos(int x) {
 38     return 1 << x;
 39 }
 40
 41 int bfs(pair<int,int> &res) {
 42     queue<Node> que;
 43     que.push(Node(ori, s, 0));
 44     vis[ori][s] = true;
 45
 46     while (!que.empty()) {
 47         Node first = que.front();
 48         que.pop();
 49         if (first.robot == t) {
 50             res.first = first.sit, res.second = first.robot;
 51             return first.time;
 52         }
 53         int ssit = first.sit, rrob = first.robot;
 54         //printf("%d %d\n", ssit, rrob);
 55
 56         for (int i = head[rrob]; i != -1; i = edge[i].next) {
 57             int v = edge[i].to;
 58             if (ssit&get_pos(v) || vis[ssit][v]) continue;
 59             vis[ssit][v] = true;
 60             que.push(Node(ssit, v, first.time + 1));
 61             pre[ssit][v] = make_pair(ssit, rrob);
 62         }
 63
 64         for (int i = 0; i < n; i++) {
 65             if (ssit&(get_pos(i))) {
 66                 for (int j = head[i]; j != -1; j = edge[j].next) {
 67                     int v = edge[j].to;
 68                     if (v == rrob || (ssit & get_pos(v))) continue;
 69                     int tmp = ssit ^ get_pos(v);
 70                     tmp ^= get_pos(i);
 71                     if (vis[tmp][rrob]) continue;
 72                     vis[tmp][rrob] = true;
 73                     que.push(Node(tmp, rrob, first.time + 1));
 74                     pre[tmp][rrob] = make_pair(ssit, rrob);
 75                 }
 76             }
 77         }
 78     }
 79     return -1;
 80 }
 81
 82 void output(pair<int,int> a) {
 83     if (a.first == ori && a.second == s) return;
 84     output(pre[a.first][a.second]);
 85     int ppre = pre[a.first][a.second].first, now = a.first;
 86
 87     if (ppre^now) {
 88         int b = -1, c = -1;
 89         for (int i = 0; i < n; i++) {
 90             if (((ppre & (1 << i)) == (1 << i)) && ((now & (1 << i)) == 0)) {
 91                 b = i;
 92             }
 93             else if (((ppre & (1 << i)) == 0) && ((now & (1 << i)) == (1 << i))) {
 94                 c = i;
 95             }
 96         }
 97         printf("%d %d\n", b + 1, c + 1);
 98     }
 99     else {
100         printf("%d %d\n", pre[a.first][a.second].second + 1, a.second + 1);
101     }
102 }
103
104 int con = 1;
105
106 int main()
107 {
108     int iCase;
109     scanf("%d", &iCase);
110     while (iCase--) {
111         init();
112         scanf("%d%d%d%d", &n, &m, &s, &t);
113         s--, t--;
114         ori = 0;
115         int x;
116         for (int i = 1; i <= m; i++) {
117             scanf("%d", &x);
118             x--;
119             ori ^= get_pos(x);
120         }
121
122         int u, v;
123         for (int i = 1; i <= n - 1; i++) {
124             scanf("%d%d", &u, &v);
125             u--, v--;
126             AddEdge(u, v);
127             AddEdge(v, u);
128         }
129
130         pair<int, int> res;
131         int ans = bfs(res);
132         printf("Case %d: %d\n", con++, ans);
133         if (ans != -1) output(res);
134         printf("\n");
135     }
136     return 0;
137 }

原文地址:https://www.cnblogs.com/npugen/p/9600200.html

时间: 2024-10-08 05:19:08

UVA12569-Planning mobile robot on Tree (EASY Version)(BFS+状态压缩)的相关文章

UVA-12569 Planning mobile robot on Tree (EASY Version) (BFS+状态压缩)

题目大意:一张无向连通图,有一个机器人,若干个石头,每次移动只能移向相连的节点,并且一个节点上只能有一样且一个东西(机器人或石头),找出一种使机器人从指定位置到另一个指定位置的最小步数方案,输出移动步骤. 题目分析:以机器人的所在位置和石头所在位置集合标记状态,状态数最多有15*2^15个.广搜之. 代码如下: # include<iostream> # include<cstdio> # include<string> # include<queue> #

Uva 12569 Planning mobile robot on Tree (EASY Version)

基本思路就是Bfs: 本题的一个关键就是如何判段状态重复. 1.如果将状态用一个int型数组表示,即假设为int state[17],state[0]代表机器人的位置,从1到M从小到大表示障碍物的位置.那么如果直接用STL中的set是会超时的,但如果自己建立一个hash方法,像这样: int getKey(State& s) { long long v = 0; for(int i=0; i<=M; ++i ) { v = v * 10 + s[i]; } return v % hashSi

UVA Planning mobile robot on Tree树上的机器人(状态压缩+bfs)

用(x,s)表示一个状态,x表示机器人的位置,s表示其他位置有没有物体.用个fa数组和act数组记录和打印路径,转移的时候判断一下是不是机器人在动. #include<bits/stdc++.h> using namespace std; const int maxn = 16; const int maxe = 32; const int MAXSTA = 491520+10; // 2^15*15 int head[maxn],to[maxe],nxt[maxe]; int ecnt; v

ZOJ 3802 Easy 2048 Again ( 状态压缩 )

题目链接~~> 做题感悟:这题很经典 ,需要模拟一下找规律,还是那句话遇到题自己应该手动推一下. 解题思路: 这题如果手动推几组数据的话就应该发现 ,如果放进队列的元素是递减的话,这样才可以连续合并,如果队列中有 a  ,b , a < b 那么 a 前面的必定不会与 b 经过合并再合并,因为越合并越大,so ~> 队列中最多才存 12 个数,可以用状态压缩压缩一下.注意要用滚动数组,不用可能超时. 代码: #include<iostream> #include<sst

Codeforces Round #316 (Div. 2) D. Tree Requests(DFS+状态压缩)

题意:给定一棵树,n个节点.每一个节点处有一个字母,结点的深度定义为节点到根结点1的距离, 有m个询问(u.v),每次回答以结点u为根的子树的深度为v的那些节点处的字母是否能组成一个回文串,特别的,空串也是回文串. 思路:首先说明推断回文串的方法,仅仅要出现次数为奇数个字母个数不超过2.那么这些字母一定能够组成回文串. 接下来考虑将树转成线性结构. 利用dfs+时间戳将结点依照深度存入一个线性结构里,Depth[i]数组里存的是深度为i的全部结点, 那么对于询问有三种情况.一种是dep[u]>=

Codeforces Round #540 (Div. 3) F1. Tree Cutting (Easy Version) 【DFS】

任意门:http://codeforces.com/contest/1118/problem/F1 F1. Tree Cutting (Easy Version) time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given an undirected tree of nn vertices. Some vert

2016 省热身赛 Earthstone: Easy Version

Earthstone: Easy Version Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description Earthstone is a famous online card game created by Lizard Entertainment. It is a collectible card game that revolves around turn-based mat

05-图2. Saving James Bond - Easy Version (25)

05-图2. Saving James Bond - Easy Version (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue This time let us consider the situation in the movie "Live and Let Die" in which James Bond, the world's most famous spy, was capture

05-2. Saving James Bond - Easy Version (25)

05-2. Saving James Bond - Easy Version (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue This time let us consider the situation in the movie "Live and Let Die" in which James Bond, the world's most famous spy, was captured