标签:
通道:http://acm.hdu.edu.cn/showproblem.php?pid=1964
题意:单回路,权值,无阻碍。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int MAX_N = 13; 8 const int MAX_M = 13; 9 const int HASH = 10007; 10 const int MAX_S = 1000007; 11 12 struct pos { 13 int right, down; 14 pos () { 15 16 } 17 pos(int _right, int _down) { 18 right = _right; 19 down = _down; 20 } 21 }b[MAX_N][MAX_M]; 22 23 struct node { 24 int head[HASH], nxt[MAX_S]; 25 long long dp[MAX_S], st[MAX_S]; 26 int cnt; 27 void init() { 28 memset(head, -1, sizeof head); 29 cnt = 0; 30 } 31 void push(long long s, long long v) { 32 int now = s % HASH; 33 for(int i = head[now]; ~i; i = nxt[i]) if(st[i] == s) { 34 dp[i] = min(dp[i], v); 35 return ; 36 } 37 st[cnt] = s; dp[cnt] = v; 38 nxt[cnt] = head[now]; 39 head[now] = cnt++; 40 } 41 }d[2]; 42 43 int n, m; 44 int ex, ey; 45 long long ans; 46 47 int find_pos(long long s, int p) { 48 return (s >> (p << 1)) & 3; 49 } 50 51 void tp(long long &s, int p, long long v) { 52 s &= (~(3ll << (p << 1))); 53 s |= (v << (p << 1)); 54 } 55 56 int find_r(long long s, int p) { 57 int cnt = 0; 58 for(int i = p; i <= m; ++i) { 59 if(find_pos(s, i) == 1) ++cnt; 60 else if(find_pos(s, i) == 2) --cnt; 61 if(!cnt) return i; 62 } 63 } 64 65 int find_l(long long s, int p) { 66 int cnt = 0; 67 for(int i = p; i >= 0; --i) { 68 if(find_pos(s, i) == 2) ++cnt; 69 else if(find_pos(s, i) == 1) --cnt; 70 if(!cnt) return i; 71 } 72 } 73 74 void blank(int i, int j, int cur) { 75 for(int k = 0; k < d[cur].cnt; ++k) { 76 long long t = d[cur].st[k]; 77 int l = find_pos(t, j - 1), r = find_pos(t, j); 78 if(l && r) { 79 if(l == 1 && r == 1) { 80 int tpos = find_r(t, j); 81 tp(t, j - 1, 0); tp(t, j, 0); tp(t, tpos, 1); 82 d[cur ^ 1].push(t, d[cur].dp[k]); 83 } else if(l == 2 && r == 1) { 84 tp(t, j - 1, 0); tp(t, j, 0); 85 d[cur ^ 1].push(t, d[cur].dp[k]); 86 } else if(l == 2 && r == 2) { 87 int tpos = find_l(t, j - 1); 88 tp(t, j - 1, 0); tp(t, j, 0); tp(t, tpos, 2); 89 d[cur ^ 1].push(t, d[cur].dp[k]); 90 } else { // 最后一个非障碍格子 91 tp(t, j - 1, 0); tp(t, j, 0); 92 if (!t) if (i == ex && j == ey) ans = min(ans, d[cur].dp[k]); 93 } 94 } else if(l) { 95 if(i < n) { 96 d[cur ^ 1].push(t, d[cur].dp[k] + b[i][j].down); 97 } 98 if(j < m) { 99 tp(t, j - 1, 0); tp(t, j, l); 100 d[cur ^ 1].push(t, d[cur].dp[k] + b[i][j].right); 101 } 102 } else if(r) { 103 if(j < m) { 104 d[cur ^ 1].push(t, d[cur].dp[k] + b[i][j].right); 105 } 106 if(i < n) { 107 tp(t, j - 1, r); tp(t, j, 0); 108 d[cur ^ 1].push(t, d[cur].dp[k] + b[i][j].down); 109 } 110 } else { // 新建 111 if(i < n && j < m) { 112 tp(t, j - 1, 1); tp(t, j, 2); 113 d[cur ^ 1].push(t, d[cur].dp[k] + b[i][j].down + b[i][j].right); 114 } 115 } 116 } 117 } 118 119 void block(int i, int j, int cur) { 120 for (int k = 0; k < d[cur].cnt; ++k) { 121 long long t = d[cur].st[k]; 122 int l = find_pos(t, j - 1), r = find_pos(t, j); 123 if (!l && !r) d[cur ^ 1].push(t, d[cur].dp[k]); 124 } 125 } 126 127 char str[17]; 128 int a[MAX_N][MAX_M]; 129 130 int main() { 131 int T; 132 scanf("%d", &T); 133 while (T-- > 0) { 134 scanf("%d%d%*c", &n ,&m); 135 gets(str); 136 for (int i = 1; i < n; ++i) { 137 gets(str); 138 for (int j = 1; j < m; ++j) 139 b[i][j].right = str[2 * j] - ‘0‘; 140 gets(str); 141 for (int j = 1; j <= m; ++j) 142 b[i][j].down = str[2 * j - 1] - ‘0‘; 143 } 144 gets(str); 145 for(int j = 1; j < m; ++j) 146 b[n][j].right = str[2 * j] - ‘0‘; 147 gets(str); 148 ex = n, ey = m; 149 int cur = 0; 150 d[cur].init(); 151 d[cur].push(0, 0); 152 ans = (int)1e9; 153 for (int i = 1; i <= n; ++i) { 154 for (int j = 1; j <= m; ++j) { 155 d[cur ^ 1].init(); 156 blank(i, j, cur); 157 cur ^= 1; 158 } 159 for (int j = 0; j < d[cur].cnt; ++j) 160 d[cur].st[j] <<= 2; 161 } 162 printf("%d\n", ans); 163 } 164 return 0; 165 } 166 167 /* 168 2 169 2 2 170 ##### 171 # 1 # 172 #2#3# 173 # 4 # 174 ##### 175 */
标签:
原文地址:http://www.cnblogs.com/Rojo/p/4636377.html