hdu 4185 Oil Skimming (二分图最大匹配,匈牙利算法)

hdu 4185题目链接 题意:给出一个nn的字符maze,‘.’代表水,‘#’代表油田。 挖油的机器一次会挖两个相邻方块。要求是必须两块必须都是油,不然会有杂质。问最多能挖多少次。 思路:和那道用12的小矩形块填充是一个思路。根据奇偶性对点标号,然后建图,匈牙利,2A. 第一遍是dfs写错了一个变量QAQ.a

/* ***********************************************
Author :111qqz
Created Time :2016年05月30日 星期一 12时53分34秒
File Name :code/hdu/4185.cpp
************************************************ */
 1#include <cstdio>
 2#include <cstring>
 3#include <iostream>
 4#include <algorithm>
 5#include <vector>
 6#include <queue>
 7#include <set>
 8#include <map>
 9#include <string>
10#include <cmath>
11#include <cstdlib>
12#include <ctime>
13#define fst first
14#define sec second
15#define lson l,m,rt<<1
16#define rson m+1,r,rt<<1|1
17#define ms(a,x) memset(a,x,sizeof(a))
18typedef long long LL;
19#define pi pair < int ,int >
20#define MP make_pair
 1using namespace std;
 2const double eps = 1E-8;
 3const int dx4[4]={1,0,0,-1};
 4const int dy4[4]={0,-1,1,0};
 5const int inf = 0x3f3f3f3f;
 6const int N=1000;
 7int n;
 8char maze[N][N];
 9int f1[N][N],f2[N][N];
10int tot1;
11int tot2;
12int cnt;
13int link[N*N];
14bool vis[N*N];
15int head[N*N];
16struct Edge
17{
18    int v;
19    int nxt;
20}edge[N*N*2];
1void addedge( int u,int v)
2{
3    edge[cnt].v = v;
4    edge[cnt].nxt = head[u];
5    head[u] = cnt;
6    cnt++;
7}
 1bool find( int u)
 2{
 3    for ( int i = head[u] ; i !=-1 ; i = edge[i].nxt)
 4    {
 5	int v = edge[i].v;
 6	//cout<<"u:"<<u<<" v:"<<v<<endl;
 7	if (vis[v]) continue;
 8	vis[v] = true;
 9	if (link[v]==-1||find(link[v]))
10	{
11	    link[v] = u;
12	    return true;
13	}
14    }
 1    return false;
 2}
 3int hungary()
 4{
 5    ms(link,-1);
 6    int res =  0;
 7    for ( int i = 1 ; i <= tot1 ; i++)
 8    {
 9	ms(vis,false);
10	if (find(i)) res++;
11    }
12    return res;
13}
14int main()
15{
16	#ifndef  ONLINE_JUDGE 
17	freopen("code/in.txt","r",stdin);
18  #endif
 1	int T;
 2	int cas = 0 ;
 3	scanf("%d",&T);
 4	while (T--)
 5	{
 6	    ms(f1,0);
 7	    ms(f2,0);
 8	    tot1 = 0 ;
 9	    tot2 = 0 ;
10	    cnt = 0 ;
11	    ms(head,-1);
1	    scanf("%d",&n);
2	    for ( int i = 0 ; i < n ; i++)
3		scanf("%s",maze[i]);
 1	    for ( int i = 0 ; i < n ; i++)
 2		for ( int j = 0 ; j < n ; j++)
 3		{
 4		    if (maze[i][j]=='.') continue;
 5		    if ((i+j)%2==0)
 6		    {
 7			f1[i][j] = ++tot1;	
 8		    }
 9		    else
10		    {
11			f2[i][j] = ++tot2;
12		    }
		}

	  //  cout<<"tot1:"<<tot1<<endl;
	  //  cout<<"tot2:"<<tot2<<endl;
 1	    for ( int i = 0 ;  i < n ; i++)
 2		for ( int j = 0 ; j < n;  j++)
 3		{
 4		    if (j+1<n&&maze[i][j]=='#'&&maze[i][j+1]=='#')
 5		    {
 6			int u = (i+j)%2==0?f1[i][j]:f2[i][j];
 7			int v = (i+j+1)%2==0?f1[i][j+1]:f2[i][j+1];
 8			if ((i+j)%2==1) swap(u,v);
 9			v+=tot1;
10			addedge(u,v);
11		    }
12		    if (i+1<n&&maze[i][j]=='#'&&maze[i+1][j]=='#')
13		    {
14			int u = (i+j)%2==0?f1[i][j]:f2[i][j];
15			int v = (i+1+j)%2==0?f1[i+1][j]:f2[i+1][j];
16			if ((i+j)%2==1) swap(u,v);
17			v+=tot1;
18			addedge(u,v);
19		    }
20		}
		int ans = hungary();
		printf("Case %d: %d\n",++cas,ans);


	}
1  #ifndef ONLINE_JUDGE  
2  fclose(stdin);
3  #endif
4    return 0;
5}