huangriq

导航

poj 2446(二分匹配)

题目:http://poj.org/problem?id=2446

思路:对相邻的格子染上不同的颜色,并对没障碍物的相邻格子之间连边,建立一个二分图,求是否每个无障碍格子都能被匹配。

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 #define M  N*N
 7 #define N  2020
 8 struct edge{
 9     int to,next;
10 }e[M];
11 int pre[N],b[N],mat[N],visit[N];
12 int cnt;
13 void add(int a,int b)
14 {
15     e[cnt].to=b;
16     e[cnt].next=pre[a];
17     pre[a]=cnt++;
18 }
19 int dfs(int u)
20 {
21     for(int edg=pre[u];edg!=0;edg=e[edg].next)
22     {
23         int v=e[edg].to;
24         if(visit[v])continue;
25         visit[v]=1;
26         if(mat[v]==-1||dfs(mat[v]))
27         {
28             mat[v]=u;
29             return true;
30         }
31     }
32     return false;
33 }
34 int n,m;
35 int dir[4][2]={-1,0,0,1,1,0,0,-1};
36 bool in(int x,int y)
37 {
38     if(x>=0&&x<n&&y>=0&&y<m)return true;
39     else return false;
40 }
41 int main()
42 {
43     int k;
44     while(scanf("%d%d%d",&n,&m,&k)!=EOF)
45     {
46         memset(b,-1,sizeof(b));
47         memset(pre,0,sizeof(pre));
48         cnt=1;
49         for(int i=1;i<=k;i++)
50         {
51             int a,c;
52             scanf("%d%d",&a,&c);
53             b[(c-1)*m+a-1]=0;
54         }
55         int cn=0;
56         for(int i=0;i<n*m;i++)
57         {
58             int x=i/m;
59             int y=i%m;
60             if((x+y)%2)continue;
61             if(b[i]==-1)cn++;
62             for(int j=0;j<4;j++)
63             {
64                 int x0=x+dir[j][0];
65                 int y0=y+dir[j][1];
66                 if(in(x0,y0))
67                 {
68                     if(b[i]==-1&&b[x0*m+y0]!=0)add(i,x0*m+y0);
69                 }
70             }
71         }
72         if(cn!=n*m-k-cn){cout<<"NO"<<endl;continue;}
73         int flag=0;
74         memset(mat,-1,sizeof(mat));
75         for(int i=0;i<n*m;i++)
76         {
77             memset(visit,0,sizeof(visit));
78             if((i%m+i/m)%2==0&&b[i]!=0)
79             {
80                 if(!dfs(i)){flag=1;break;}
81             }
82         }
83         if(flag)cout<<"NO"<<endl;
84         else cout<<"YES"<<endl;
85     }
86     return 0;
87 }

 

posted on 2012-05-12 22:51  huangriq  阅读(179)  评论(0编辑  收藏  举报