hdu 4568 bfs + 状压dp

//这题的数据是不是有问题... 不考虑宝藏一个也拿不到也能AC...

  1 #include "bits/stdc++.h"
  2 using namespace std;
  3 const int INF = 0x3f3f3f3f;
  4 int T;
  5 int N, M;
  6 int mat[210][210];
  7 int K;
  8 int tot_tra, tra[210][210];
  9
 10 //dp parameters
 11 int dis_tra_broder[20], dis_tra_tra[20][20];
 12 int dp[10000][20];
 13
 14 //bfs parameters
 15 struct Node
 16 {
 17     int row, col;
 18     int cost;
 19     bool operator< (const Node &tmp) const
 20     {
 21         return cost > tmp.cost;
 22     }
 23 }now, Next, begin_pos[20];
 24
 25 int dis[210][210];
 26 bool vis[210][210];
 27
 28 inline bool check_border(int row, int col)
 29 {
 30     if(row == 1 || row == N || col == 1 || col == M) {
 31         return 1;
 32     }
 33     return 0;
 34 }
 35
 36 inline bool check(int row, int col)
 37 {
 38     if(row < 1 || row > N || col < 1 || col > M) {
 39         return 0;
 40     }
 41     return 1;
 42 }
 43
 44
 45 int dx[] = {0, 0, -1, 1};
 46 int dy[] = {-1, 1, 0, 0};
 47
 48 void bfs(int index_tra)
 49 {
 50     priority_queue<Node> q;
 51     q.push(begin_pos[index_tra]);
 52     memset(vis, 0, sizeof(vis));
 53     memset(dis, INF, sizeof(dis));
 54     dis[ begin_pos[index_tra].row ][ begin_pos[index_tra].col ] = 0;
 55     while(!q.empty()) {
 56         now = q.top();
 57         q.pop();
 58         if(vis[now.row][now.col]) {
 59             continue;
 60         }
 61         vis[now.row][now.col] = 1;
 62         if(tra[now.row][now.col]) {
 63             dis_tra_tra[index_tra][ tra[now.row][now.col] ] = now.cost;
 64         }
 65         if(check_border(now.row, now.col)) {
 66             dis_tra_broder[index_tra] = min(dis_tra_broder[index_tra], now.cost);
 67         }
 68         int i;
 69         for(i = 0; i < 4; ++i) {
 70             Next.row = now.row + dx[i];
 71             Next.col = now.col + dy[i];
 72             if(check(Next.row, Next.col) && mat[Next.row][Next.col] != -1) {
 73                 Next.cost = now.cost + mat[Next.row][Next.col];
 74                 if(Next.cost < dis[Next.row][Next.col]) {
 75                     dis[Next.row][Next.col] = Next.cost;
 76                     q.push(Next);
 77                 }
 78             }
 79         }
 80     }
 81 }
 82
 83 int main()
 84 {
 85     scanf("%d", &T);
 86     while(T--) {
 87         memset(tra, 0, sizeof(tra));
 88         memset(dis_tra_broder, INF, sizeof(dis_tra_broder));
 89         memset(dis_tra_tra, INF, sizeof(dis_tra_tra));
 90         memset(dp, INF, sizeof(dp));
 91         scanf("%d%d", &N, &M);
 92         int i, j;
 93         for(i = 1; i <= N; ++i) {
 94             for(j = 1; j <= M; ++j) {
 95                 scanf("%d", &mat[i][j]);
 96             }
 97         }
 98         scanf("%d", &K);
 99         int row, col;
100         for(i = 1; i <= K; ++i) {
101             scanf("%d%d", &row, &col);
102             ++row;
103             ++col;
104             tra[row][col] = i;
105             begin_pos[i].row = row;
106             begin_pos[i].col = col;
107 //            begin_pos[i].cost = 0;
108         }
109         for(i = 1; i <= K; ++i) {
110             bfs(i);
111         }
112         int tot_s = (1 << K) - 1;
113         int s, step_s, u, pre_s, pre_step_s, v;
114         for(u = 1; u <= K; ++u) {
115             dp[(1 << (u - 1))][u] = dis_tra_broder[u] + mat[begin_pos[u].row][begin_pos[u].col];
116         }
117         for(s = 3; s <= tot_s; ++s) {
118             for(u = 1; u <= K; ++u) {
119                 step_s = (1 << (u - 1));
120                 if((s & step_s) && (step_s != s)) {
121                     pre_s = s ^ step_s;
122                     for(v = 1; v <= K; ++v) {
123                         pre_step_s = (1 << (v - 1));
124                         if(pre_s & pre_step_s) {
125                             dp[s][u] = min(dp[s][u], dp[pre_s][v] + dis_tra_tra[v][u]);
126                         }
127                     }
128                 }
129             }
130         }
131         int res = INF;
132         for(u = 1; u <= K; ++u) {
133             res = min(res, dp[tot_s][u] + dis_tra_broder[u]);
134         }
135         printf("%d\n", res);
136     }
137 }
时间: 2024-11-08 21:42:03

hdu 4568 bfs + 状压dp的相关文章

HDU 3681 BFS&amp;状压DP&amp;二分

N*M矩阵,从F点出发,走完所有的Y点,每走一格花费1点电量,走到G点时,电量充满,D不可到达,问起始时的最小满电量可以走完所有Y,Y和G一共最多15个 先BFS出所有的F,Y,G之间的最短距离. 然后二分起始电量,对每个电量,做状压DP判断是否可行 #include "stdio.h" #include "string.h" #include "queue" using namespace std; int inf=0x3f3f3f3f; in

HDU 4856 Tunnels(BFS+状压DP)

HDU 4856 Tunnels 题目链接 题意:给定一些管道,然后管道之间走是不用时间的,陆地上有障碍,陆地上走一步花费时间1,求遍历所有管道需要的最短时间,每个管道只能走一次 思路:先BFS预处理出两两管道的距离,然后状态压缩DP求解,dp[s][i]表示状态s,停在管道i时候的最小花费 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using

HDU 4284Travel(状压DP)

HDU 4284    Travel 有N个城市,M条边和H个这个人(PP)必须要去的城市,在每个城市里他都必须要“打工”,打工需要花费Di,可以挣到Ci,每条边有一个花费,现在求PP可不可以从起点1走完所有的他必须要去的城市,打完所有的工,并且成功回到起点1 由于H<=15,所以显然可以状压,预处理这些都必须去的城市之间的最短距离(可以floyd),然后状压DP[S][i]表示他到达了S这些城市后正处在第i个城市里(所以S & (1<<i) != 0)的剩余的最大的钱的数量,然

HDU-3502-Huson&#39;s Adventure Island(BFS+状压DP)

Problem Description A few days ago, Tom was tired of all the PC-games, so he went back to some old FC-games. "Hudson's Adventure Island" was his favorite which he had played thousands of times. But to his disappointed, the more he played, the mo

HDU 3001 Travelling 状压DP

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题意:还是环游地图的问题,只不过这回旅行者对自己有着严格的要求,地图上每个点的经过次数不能超过两次. 思路:依然是状压DP问题,根上一道很像,只不过这次对于每个点来说有三种状态,分别是未经过,经过一次,经过两次.所以要用三进制的数来进行状态压缩,这个关键点想明白了其他的和上一道基本一样了.对于我来说需要注意的是:能够到达某一个点经过了两次的状态的前一个状态是这个点已经经过了一次的状态,而不是从来未

HDU-4856 Tunnels (BFS+状压DP)

Problem Description Bob is travelling in Xi’an. He finds many secret tunnels beneath the city. In his eyes, the city is a grid. He can’t enter a grid with a barrier. In one minute, he can move into an adjacent grid with no barrier. Bob is full of cur

POJ 2688 BFS+状压DP

标准的TSP问题 m*n矩阵,有不超过10个需要走到的点,给出起点,问走最少的步子把所有点走完 BFS出每个必须走到的点的最短距离 然后状压DP即可 #include "stdio.h" #include "string.h" #include "queue" using namespace std; const int dir[4][2]={ {1,0},{-1,0},{0,1},{0,-1} }; int inf=0x7fffffff; in

HDU-3681-Prison Break(BFS+状压DP+二分)

Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one day, the king of Rompire was captured by human beings. His thinking circuit was changed by human and thus became a tyrant. All those who are against him

QDUOJ 来自xjy的签到题(bfs+状压dp)

来自xjy的签到题 Description 爱丽丝冒险来到了红皇后一个n*n大小的花园,每个格子由'.'或'#'表示,'.'表示爱丽丝可以到达这个格子,‘#’表示爱丽丝不能到达这个格子,爱丽丝每1分钟可以移动到非'#'的相邻格子(与当前所在格子具有公共边).花园下面有m个隧道,每个隧道有一个出口和一个入口.当爱丽丝到达隧道的入口时,她可以选择(也可以不选择)进入隧道入口,并通过隧道一次,然后立即(不花费时间)出现在隧道出口.爱丽丝一开始可以降临在花园的任何地方.有好奇心的爱丽丝想知道,她通过所有