原题连接:http://acm.hdu.edu.cn/showproblem.php?pid=4185
题意:题目描述的很垃圾。。简化一下,看题中的图,求最多有多少对#,(相邻的两个是一对)
代码:
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;
const int Max = 19000;
vector<int>V[Max];
int link[Max],use[Max];
char Map[700][700];
int Dye_loop[700][700];
struct hh
{
int x,y;
bool operator <(const hh &t1)const
{
return x<t1.x||x==t1.x&&y<t1.y;
}
};
void init(int n)
{
int i;
for(i=0;i<=n;i++)
V[i].clear();
}
bool Dfs(int v)
{
int i,j,k;
for(i=0;i<V[v].size();i++)
{
k=V[v][i];
if(!use[k])
{
use[k]=1;
if(!link[k]||Dfs(link[k]))
{
link[k]=v;
return true;
}
}
}
return false;
}
int MaxMatch(int n)
{
int i,j,ans=0;
memset(link,0,sizeof(link));
for(i=1;i<=n;i++)
{
memset(use,0,sizeof(use));
if(Dfs(i))
ans++;
}
return ans;
}
void Dye_Dfs(int x,int y,int z,int n)
{
//printf("x: %d y: %d z: %d\n",x,y,z);
Dye_loop[x][y] = z;
if(x-1>=1&&Dye_loop[x-1][y]==0&&Map[x-1][y]=='#')
{
if(z == 1)
Dye_Dfs(x-1,y,2,n);
if(z == 2)
Dye_Dfs(x-1,y,1,n);
}
if(y-1>=1&&Dye_loop[x][y-1]==0&&Map[x][y-1]=='#')
{
if(z == 1)
Dye_Dfs(x,y-1,2,n);
if(z == 2)
Dye_Dfs(x,y-1,1,n);
}
if(x+1<=n&&Dye_loop[x+1][y]==0&&Map[x+1][y]=='#')
{
if(z == 1)
Dye_Dfs(x+1,y,2,n);
if(z == 2)
Dye_Dfs(x+1,y,1,n);
}
if(y+1<=n&&Dye_loop[x][y+1]==0&&Map[x][y+1]=='#')
{
if(z == 1)
Dye_Dfs(x,y+1,2,n);
if(z == 2)
Dye_Dfs(x,y+1,1,n);
}
}
//void display_dye(int n)
//{
// int i,j;
// for(i=1;i<=n;i++)
// {
// for(j=1;j<=n;j++)
// cout<<Dye_loop[i][j]<<" ";
// cout<<endl;
// }
//}
void Dye(int n)
{
int i,j;
memset(Dye_loop,0,sizeof(Dye_loop));
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(Dye_loop[i][j]==0&&Map[i][j] == '#')
Dye_Dfs(i,j,1,n);
}
}
}
int Build(int n)
{
int i,j,k;
int mn=0,sum=0;
map<hh,int>M;
map<hh,int>::iterator it;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(Dye_loop[i][j] == 1)
{
sum++;
int x , y;
x = i-1 , y = j;
if(x>=1&&Dye_loop[x][y]==2)
{
struct hh t1={x,y};
it = M.find(t1);
if(it!=M.end())//ok
{
V[sum].push_back((*it).second);
}
else
{
M[t1] = ++mn;
V[sum].push_back(mn);
}
}
x = i ,y = j-1;
if(y>=1&&Dye_loop[x][y]==2)
{
struct hh t1={x,y};
it = M.find(t1);
if(it!=M.end())//ok
{
V[sum].push_back((*it).second);
}
else
{
M[t1] = ++mn;
V[sum].push_back(mn);
}
}
x = i+1 , y = j;
if(x<=n&&Dye_loop[x][y]==2)
{
struct hh t1={x,y};
it = M.find(t1);
if(it!=M.end())//ok
{
V[sum].push_back((*it).second);
}
else
{
M[t1] = ++mn;
V[sum].push_back(mn);
}
}
x = i , y = j+1;
if(y<=n&&Dye_loop[x][y]==2)
{
struct hh t1={x,y};
it = M.find(t1);
if(it!=M.end())//ok
{
V[sum].push_back((*it).second);
}
else
{
M[t1] = ++mn;
V[sum].push_back(mn);
}
}
}
}
}
return sum;
}
int main()
{
int i,j,n,m,k,ncase;
scanf("%d",&ncase);
for(k=1;k<=ncase;k++)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%s",Map[i]+1);
Dye(n);
//display_dye(n);
m =Build(n);
printf("Case %d: ",k);
printf("%d\n",MaxMatch(m));
init(m);
}
}
写的很垃圾,想xiaod要了个time 0 的代码,贴上膜拜!!
#include <map>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 36005;
const int M = 100005;
struct Vertex
{
int head;
}V[N];
struct Edge
{
int v,next;
}E[M];
int n,m,top,match[N];
bool used[N];
char str[N][N];
const int dx[] = {1,0,-1,0};
const int dy[] = {0,1,0,-1};
void Init()
{
top = 0;
memset(V,-1,sizeof(V));
}
void Add_Edge(int u,int v)
{
E[top].v = v;
E[top].next = V[u].head;
V[u].head = top++;
}
bool dfs(int u)
{
for(int i=V[u].head;~i;i=E[i].next)
{
int v = E[i].v;
if(!used[v])
{
used[v] = true;
if(!match[v] || dfs(match[v]))
{
match[v] = u;
return true;
}
}
}
return false;
}
int maxMatch(int n)
{
int ans = 0;
memset(match,0,sizeof(match));
for(int i=1;i<=n;i++)
{
memset(used,false,sizeof(used));
if(dfs(i))
++ans;
}
return ans;
}
int main()
{
int z,__n,ncase=0;
scanf("%d",&z);
map< pair<int,int>,int > M[2];
while(z--)
{
Init();
M[0].clear();
M[1].clear();
scanf("%d",&__n);
n = 0 , m = 0;
for(int i=1;i<=__n;i++)
scanf("%s",str[i]+1);
for(int i=1;i<=__n;i++)
{
for(int j=1;str[i][j];j++)
{
if(str[i][j] != '#')
continue;
int k = (i+j)&1;
if(!k)
{
M[0][make_pair(i,j)] = ++n;
int u = n;
for(int ii=0;ii<4;ii++)
{
int x = i + dx[ii] , y = j + dy[ii];
if(!(x>=1 && x<=__n && y>=1 && y<=__n && str[x][y]=='#'))
continue;
int v;
if(M[1].count(make_pair(x,y)))
v = M[1][make_pair(x,y)];
else
v = M[1][make_pair(x,y)] = 18000 + (++m);
Add_Edge(u,v);
}
}
else
{
if(!M[1].count(make_pair(i,j)))
M[1][make_pair(i,j)] = 18000 + (++m);
}
}
}
// for(map< pair<int,int>,int >::iterator it=M[0].begin();it!=M[0].end();++it)
// printf("(%d,%d)\n",it->first.first,it->first.second);
printf("Case %d: %d\n",++ncase,maxMatch(n));
}
return 0;
}