标签:
题意:有一个地图.代表水#代表油每个单元格是10*10的,现有10*20的勺子可以提取出水上漂浮的油,问最多可以提取几勺的油;
每次提取的时候勺子放的位置都要是油,不然就被污染而没有价值了;
所以就是求最大匹配的;关键是建立边与边的关系,可以让有油的地方编号为1 2 3。。。然后再连接上下左右的点;
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<queue> using namespace std; #define N 660 #define INF 0xfffffff int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1} }; int G[N][N], a[N][N], cnt, vis[N], used[N];///a[i][j]代表这个位置#的编号从1开始; char maps[N][N]; bool Find(int u) { for(int i=1; i<cnt; i++) { if(!vis[i] && G[u][i]) { vis[i] = 1; if(!used[i] || Find(used[i])) { used[i] = u; return true; } } } return false; } int main() { int T, t=1, n; scanf("%d", &T); while(T--) { scanf("%d", &n); cnt=1; memset(used, 0, sizeof(used)); memset(G, 0, sizeof(G)); memset(a, 0, sizeof(a)); memset(maps, 0, sizeof(maps)); for(int i=0; i<n; i++) { scanf("%s", maps[i]); for(int j=0; j<n; j++) { if(maps[i][j] == ‘#‘) a[i][j] = cnt++; } } for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { if(maps[i][j]==‘#‘) for(int k=0; k<4; k++)/// 上下左右建立关系; { int x = i+dir[k][0]; int y = j+dir[k][1]; if(x>=0 && y>=0 && x<n && y<n && maps[x][y]==‘#‘) { int p=a[x][y]; int q=a[i][j]; G[p][q] = G[q][p] = 1;///建图; } } } } int ans = 0; for(int i=1; i<cnt; i++) { memset(vis, 0, sizeof(vis)); if(Find(i)) ans++; } printf("Case %d: %d\n", t++, ans/2); } return 0; }
标签:
原文地址:http://www.cnblogs.com/zhengguiping--9876/p/4722349.html