[HDOJ4185]Oil Skimming(二分图最大匹配,匈牙利算法xKM算法)

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4185

题意:一片(n*10)*(n*10)的平面上有油(#)也有水(.),现在有规格为10*20的铲子(相当于每个铲子可以覆盖1*2或者2*1的平面)想要把油盖上,铲子不能相交。问如何分配才能把油尽可能多地覆盖到。

 

思路:给每个#编号,按照编号,油如果有相邻的,则给他们的编号建一条边。注意编号的范围变成600*600了,建图大一倍要注意。

  1 /*
  2 ━━━━━┒ギリギリ♂ eye!
  3 ┓┏┓┏┓┃キリキリ♂ mind!
  4 ┛┗┛┗┛┃\○/
  5 ┓┏┓┏┓┃ /
  6 ┛┗┛┗┛┃ノ)
  7 ┓┏┓┏┓┃
  8 ┛┗┛┗┛┃
  9 ┓┏┓┏┓┃
 10 ┛┗┛┗┛┃
 11 ┓┏┓┏┓┃
 12 ┛┗┛┗┛┃
 13 ┓┏┓┏┓┃
 14 ┃┃┃┃┃┃
 15 ┻┻┻┻┻┻
 16 */
 17 #include <algorithm>
 18 #include <iostream>
 19 #include <iomanip>
 20 #include <cstring>
 21 #include <climits>
 22 #include <complex>
 23 #include <fstream>
 24 #include <cassert>
 25 #include <cstdio>
 26 #include <bitset>
 27 #include <vector>
 28 #include <deque>
 29 #include <queue>
 30 #include <stack>
 31 #include <ctime>
 32 #include <set>
 33 #include <map>
 34 #include <cmath>
 35 using namespace std;
 36 #define fr first
 37 #define sc second
 38 #define cl clear
 39 #define BUG puts("here!!!")
 40 #define W(a) while(a--)
 41 #define pb(a) push_back(a)
 42 #define Rint(a) scanf("%d", &a)
 43 #define Rs(a) scanf("%s", a)
 44 #define Cin(a) cin >> a
 45 #define FRead() freopen("in", "r", stdin)
 46 #define FWrite() freopen("out", "w", stdout)
 47 #define Rep(i, len) for(int i = 0; i < (len); i++)
 48 #define For(i, a, len) for(int i = (a); i < (len); i++)
 49 #define Cls(a) memset((a), 0, sizeof(a))
 50 #define Clr(a, x) memset((a), (x), sizeof(a))
 51 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
 52 #define lrt rt << 1
 53 #define rrt rt << 1 | 1
 54 #define pi 3.14159265359
 55 #define RT return
 56 #define lowbit(x) x & (-x)
 57 #define onecnt(x) __builtin_popcount(x)
 58 typedef long long LL;
 59 typedef long double LD;
 60 typedef unsigned long long ULL;
 61 typedef pair<int, int> pii;
 62 typedef pair<string, int> psi;
 63 typedef pair<LL, LL> pll;
 64 typedef map<string, int> msi;
 65 typedef vector<int> vi;
 66 typedef vector<LL> vl;
 67 typedef vector<vl> vvl;
 68 typedef vector<bool> vb;
 69 
 70 const int maxn = 660;
 71 const int inf = 0x3f3f3f3f;
 72 int dx[4] = {1, -1, 0, 0};
 73 int dy[4] = {0, 0, 1, -1};
 74 int n;
 75 char tmp[maxn];
 76 int order[maxn*maxn], ocnt;
 77 int nu,nv;
 78 int G[maxn][maxn], mp[maxn][maxn];
 79 bool vis[maxn*maxn];
 80 int linker[maxn*maxn];
 81 
 82 bool dfs(int u) {
 83     Rep(v, nv) {
 84         if(G[u][v] && !vis[v]) {
 85             vis[v] = 1;
 86             if(linker[v] == -1 || dfs(linker[v])) {
 87                 linker[v] = u;
 88                 return 1;
 89             }
 90         }
 91     }
 92     return 0;
 93 }
 94 
 95 int hungary() {
 96     int ret = 0;
 97     Clr(linker, -1);
 98     Rep(u, nu) {
 99         Cls(vis);
100         if(dfs(u)) ret++;
101     }
102     return ret;
103 }
104 
105 int main() {
106     // FRead();
107     int T, _ = 1;
108     Rint(T);
109     W(T) {
110         Rint(n);
111         Rep(i, n+10) Rep(j, n+10) mp[i][j] = inf; ocnt = 0;
112         Rep(i, n) {
113             Rs(tmp);
114             Rep(j, n) {
115                 if(tmp[j] == '#') mp[i][j] = ocnt++;
116             }
117         }
118         nu = nv = ocnt; Cls(G); 
119         Rep(i, n) {
120             Rep(j, n) {
121                 if(mp[i][j] != inf) {
122                     Rep(k, 4) {
123                         int x = i + dx[k];
124                         int y = j + dy[k];
125                         if(mp[x][y] != inf) {
126                             G[mp[i][j]][mp[x][y]] = 1;
127                         }
128                     }
129                 }
130             }
131         }
132         printf("Case %d: %d\n", _++, hungary()/2);
133     }
134     RT 0;
135 }

 

  1 /*
  2 ━━━━━┒ギリギリ♂ eye!
  3 ┓┏┓┏┓┃キリキリ♂ mind!
  4 ┛┗┛┗┛┃\○/
  5 ┓┏┓┏┓┃ /
  6 ┛┗┛┗┛┃ノ)
  7 ┓┏┓┏┓┃
  8 ┛┗┛┗┛┃
  9 ┓┏┓┏┓┃
 10 ┛┗┛┗┛┃
 11 ┓┏┓┏┓┃
 12 ┛┗┛┗┛┃
 13 ┓┏┓┏┓┃
 14 ┃┃┃┃┃┃
 15 ┻┻┻┻┻┻
 16 */
 17 #include <algorithm>
 18 #include <iostream>
 19 #include <iomanip>
 20 #include <cstring>
 21 #include <climits>
 22 #include <complex>
 23 #include <fstream>
 24 #include <cassert>
 25 #include <cstdio>
 26 #include <bitset>
 27 #include <vector>
 28 #include <deque>
 29 #include <queue>
 30 #include <stack>
 31 #include <ctime>
 32 #include <set>
 33 #include <map>
 34 #include <cmath>
 35 using namespace std;
 36 #define fr first
 37 #define sc second
 38 #define cl clear
 39 #define BUG puts("here!!!")
 40 #define W(a) while(a--)
 41 #define pb(a) push_back(a)
 42 #define Rint(a) scanf("%d", &a)
 43 #define Rs(a) scanf("%s", a)
 44 #define Cin(a) cin >> a
 45 #define FRead() freopen("in", "r", stdin)
 46 #define FWrite() freopen("out", "w", stdout)
 47 #define Rep(i, len) for(int i = 0; i < (len); i++)
 48 #define For(i, a, len) for(int i = (a); i < (len); i++)
 49 #define Cls(a) memset((a), 0, sizeof(a))
 50 #define Clr(a, x) memset((a), (x), sizeof(a))
 51 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
 52 #define lrt rt << 1
 53 #define rrt rt << 1 | 1
 54 #define pi 3.14159265359
 55 #define RT return
 56 #define lowbit(x) x & (-x)
 57 #define onecnt(x) __builtin_popcount(x)
 58 typedef long long LL;
 59 typedef long double LD;
 60 typedef unsigned long long ULL;
 61 typedef pair<int, int> pii;
 62 typedef pair<string, int> psi;
 63 typedef pair<LL, LL> pll;
 64 typedef map<string, int> msi;
 65 typedef vector<int> vi;
 66 typedef vector<LL> vl;
 67 typedef vector<vl> vvl;
 68 typedef vector<bool> vb;
 69 
 70 const int maxn = 660;
 71 int dx[4] = {1, -1, 0, 0};
 72 int dy[4] = {0, 0, 1, -1};
 73 int n;
 74 char tmp[maxn];
 75 int order[maxn*maxn], ocnt;
 76 const int inf = 0x3f3f3f3f;
 77 int nx,ny;
 78 int G[maxn][maxn], mp[maxn][maxn];
 79 int linker[maxn*maxn],lx[maxn*maxn],ly[maxn*maxn];
 80 int slack[maxn*maxn];
 81 bool visx[maxn*maxn],visy[maxn*maxn];
 82 
 83 bool dfs(int x) {
 84     visx[x] = true;
 85     for(int y = 0; y < ny; y++) {
 86         if(visy[y])continue;
 87         int tmp = lx[x] + ly[y] - G[x][y];
 88         if(tmp == 0) {
 89             visy[y] = true;
 90             if(linker[y] == -1 || dfs(linker[y])) {
 91                 linker[y] = x;
 92                 return true;
 93             }
 94         }
 95         else if(slack[y] > tmp)
 96             slack[y] = tmp;
 97     }
 98     return false;
 99 }
100 int km() {
101     memset(linker,-1,sizeof(linker));
102     memset(ly,0,sizeof(ly));
103     for(int i = 0;i < nx;i++) {
104         lx[i] = -inf;
105         for(int j = 0;j < ny;j++)
106             if(G[i][j] > lx[i])
107                 lx[i] = G[i][j];
108     }
109     for(int x = 0;x < nx;x++) {
110         for(int i = 0;i < ny;i++)
111             slack[i] = inf;
112         while(true) {
113             memset(visx,false,sizeof(visx));
114             memset(visy,false,sizeof(visy));
115             if(dfs(x))break;
116             int d = inf;
117             for(int i = 0;i < ny;i++)
118                 if(!visy[i] && d > slack[i])
119                     d = slack[i];
120             for(int i = 0;i < nx;i++)
121                 if(visx[i])
122                     lx[i] -= d;
123             for(int i = 0;i < ny;i++) {
124                 if(visy[i])ly[i] += d;
125                 else slack[i] -= d;
126             }
127         }
128     }
129     int res = 0;
130     for(int i = 0;i < ny;i++)
131         if(linker[i] != -1)
132             res += G[linker[i]][i];
133     return res;
134 }
135 
136 int main() {
137     // FRead();
138     int T, _ = 1;
139     Rint(T);
140     W(T) {
141         Rint(n);
142         Rep(i, n+10) Rep(j, n+10) mp[i][j] = inf; ocnt = 0;
143         Rep(i, n) {
144             Rs(tmp);
145             Rep(j, n) {
146                 if(tmp[j] == '#') mp[i][j] = ocnt++;
147             }
148         }
149         nx = ny = ocnt; Cls(G); 
150         Rep(i, n) {
151             Rep(j, n) {
152                 if(mp[i][j] != inf) {
153                     Rep(k, 4) {
154                         int x = i + dx[k];
155                         int y = j + dy[k];
156                         if(mp[x][y] != inf) {
157                             G[mp[i][j]][mp[x][y]] = 1;
158                         }
159                     }
160                 }
161             }
162         }
163         printf("Case %d: %d\n", _++, km()/2);
164     }
165     RT 0;
166 }
KM

 

posted @ 2016-08-25 11:12  Kirai  阅读(288)  评论(0编辑  收藏  举报