//方便以后回顾错误//http://acm.hdu.edu.cn/showproblem.php?pid=1044//题意 给定起点、终点和图上的宝藏的权值,问 在规定的步数内能否从起点走到终点;若能走到,可携带宝藏的总价值最大是多少 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<queue> 5 #include<vector> 6 using namespace std; 7 8 const int dx[] = {-1, 1, 0, 0}; 9 const int dy[] = { 0, 0,-1, 1}; 10 11 int n, m, time, p;// 1<=n,m<=50 1<=l<=1000000 1<=p<=10 12 char G[55][55];// 图 13 int vis[55][55]; 14 int dis[15][15];// 两个点之间的距离(编号) 15 int bin[15];// 存宝藏的价值 16 17 typedef pair<int, int> Pair; 18 vector<Pair > v;// 存起点、终点和宝藏的坐标 19 int len;// v的大小 20 21 struct node { 22 int x, y, step; 23 node(int x,int y,int step):x(x),y(y),step(step){} 24 }; 25 26 bool can_go(node b) { 27 if(b.x < 0 || b.x >= n || b.y < 0 || b.y >= m || G[b.x][b.y] == ‘*‘ || vis[b.x][b.y]) return false; 28 return true; 29 } 30 31 void bfs(int s, int e) { 32 dis[s][e] = dis[e][s] = 1000005;/* 这一步没加,改了半个下午bug。因为可能s达不到e 所以要先赋值为最大步长,这里bfs不是返回距离,以前都是返回距离或者bool,换个写法没考虑到这细节。。。*/ 33 memset(vis, 0, sizeof(vis)); 34 node a(v[s].first, v[s].second, 0); 35 vis[v[s].first][v[s].second] = 1; 36 queue<node> q; 37 q.push(a); 38 while(!q.empty()) { 39 a = q.front(); 40 q.pop(); 41 if(a.x == v[e].first && a.y == v[e].second) { 42 dis[s][e] = dis[e][s] = a.step; 43 break; 44 } 45 for(int i = 0; i != 4; ++i) { 46 node b(a.x+dx[i], a.y+dy[i], a.step+1); 47 if(can_go(b)) { 48 q.push(b); 49 vis[b.x][b.y] = 1; 50 } 51 } 52 } 53 } 54 55 int maxn; 56 int all_value; 57 int vis2[15]; 58 void dfs(int cur, int step, int sum) { 59 if(step > time) return; 60 if(maxn == all_value) return;//剪枝 所有宝藏都找到了。。。 61 if(cur == len-1) { 62 //printf("-----\n"); 63 if(sum > maxn) maxn = sum; 64 return; 65 } 66 for(int i = 0; i != len; ++i) { 67 if(!vis2[i] && cur != i) { 68 //printf("----\n"); 69 vis2[i] = 1; 70 dfs(i, step+dis[cur][i], sum+bin[i]); 71 vis2[i] = 0; 72 } 73 } 74 } 75 76 int main() { 77 int T, cnt = 0; 78 scanf("%d", &T); 79 while(T--) { 80 scanf("%d%d%d%d", &m, &n, &time, &p); 81 memset(bin, 0, sizeof(bin)); 82 all_value = 0; 83 for(int i = 1; i <= p; ++i) { 84 scanf("%d", &bin[i]); 85 all_value += bin[i]; 86 } 87 bin[0] = bin[p+1] = 0; 88 len = 2+p; 89 //Pair init_p = make_pair(-1, -1); 90 v.clear(); 91 v.resize(50); 92 for(int i = 0; i != n; ++i) { 93 scanf("%s", G[i]); 94 for(int j = 0; j != m; ++j) { 95 if(G[i][j] == ‘@‘) { v[0] = make_pair(i, j); } 96 else if(G[i][j] == ‘<‘) { v[len-1] = make_pair(i, j); } 97 else if(G[i][j] >= ‘A‘ && G[i][j] <= ‘J‘) { v[G[i][j]-‘A‘+1] = make_pair(i, j); } 98 } 99 } 100 //printf("%d\n", v.size()); 101 for(int i = 0; i != len-1; ++i) { 102 for(int j = i+1; j != len; ++j) { 103 bfs(i, j);// bfs所有结点(起点、宝藏、终点) 两两之间的最短距离 104 //printf("%d\n", dis[i][j]); 105 } 106 //printf("%d %d\n", v[i].first, v[i].second); 107 } 108 //printf("------\n"); 109 maxn = -1; 110 memset(vis2, 0, sizeof(vis2)); 111 vis2[0] = 1; 112 dfs(0, 0, 0); 113 if(cnt) printf("\n"); 114 printf("Case %d:\n", ++cnt); 115 if(maxn == -1) printf("Impossible\n"); 116 else printf("The best score is %d.\n", maxn); 117 } 118 return 0; 119 }
原文地址:https://www.cnblogs.com/pupil-xj/p/11569138.html
时间: 2024-10-11 17:43:00