100729 D 解题报告
题目大意:
求目标图案能否用这样的图形拼出来

链接:http://codeforces.com/gym/100729/attachments/download/3754/20112012-northwestern-european-regional-contest-nwerc-2011-en.pdf
解法:网络流
建立s和t
对于第奇数行白的建在图的左边,偶数行白的在右边
那么..
中间连着所有的黑点
形成了大概长这个样子的图...

就是这样的,直接最大流一遍即可..
代码如下:
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<sstream>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
struct edge
{
int y;
int weight;
edge * next;
edge * anti;
};
const int maxn=500005;
const int inf=99999999;
edge * li[maxn];
int top=0;
edge * new_edge()
{
static edge a[4000005];
return &a[top++];
}
edge * inserts(int x,int y,int z)
{
edge * t=new_edge();
t->y=y;
t->weight=z;
t->next=li[x];
li[x]=t;
return t;
}
void insert_edge(int x,int y,int z)
{
edge * t1=inserts(x,y,z);
edge * t2=inserts(y,x,z);
t1->anti=t2;
t2->anti=t1;
}
int dist[maxn];
bool bfs(int s,int t)
{
memset(dist,-1,sizeof(dist));
dist[s]=0;
int front=0,rail=1;
static int que[maxn];
que[0]=s;
for (;front<rail;front++)
{
int now=que[front];
edge * x;
for (x=li[now];x!=0;x=x->next)
{
if ((dist[x->y]==-1)&&(x->weight>0))
{
dist[x->y]=dist[now]+1;
if (x->y==t) return true;
que[rail++]=x->y;
}
}
}
return false;
}
int max_flow(int s,int t)
{
int tot=0;
static edge * cur[maxn];
static edge * path[maxn];
static int pre[maxn];
for (;bfs(s,t);)
{
memset(pre,-1,sizeof(pre));
memset(path,0,sizeof(path));
memcpy(cur,li,sizeof(cur));
int now=s;
for (;dist[s]!=-1;)
{
if (now==t)
{
int min_ans=inf;
int temp=now;
for (;temp!=s;temp=pre[temp])
{
min_ans=min(min_ans,path[temp]->weight);
}
tot+=min_ans;
temp=now;
for (;temp!=s;temp=pre[temp])
{
path[temp]->weight-=min_ans;
path[temp]->anti->weight+=min_ans;
}
now=s;
}
edge * x;
for (x=cur[now];x!=0;x=x->next)
{
if ((dist[x->y]==dist[now]+1)&&(x->weight>0))
{
pre[x->y]=now;
path[x->y]=x;
cur[now]=x;
now=x->y;
break;
}
}
if (x==0)
{
dist[now]=-1;
now=pre[now];
}
}
}
return tot;
}
int n,m;
bool vaild(int x,int y)
{
return ((x<n)&&(y<m)&&(x>=0)&&(y>=0));
}
int get_id(int x,int y)
{
return x*m+y;
}
char a[505][505];
int main()
{
#ifdef absi2011
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
int t;
scanf("%d",&t);
int zu;
for (zu=0;zu<t;zu++)
{
scanf("%d%d",&n,&m);
int i,j;
int sum_b=0,sum_w=0;
for (i=0;i<n;i++)
{
scanf("%s",a[i]);
}
int s=n*m*2;
int t=n*m*2+1;
memset(li,0,sizeof(li));
top=0;
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
if (a[i][j]=='W')
{
sum_w++;
if (((i&1))==1) insert_edge(s,get_id(i,j),1);
if (((i&1))==0) insert_edge(get_id(i,j)+n*m,t,1);
}
else if (a[i][j]=='B')
{
sum_b++;
insert_edge(get_id(i,j),get_id(i,j)+n*m,1);
if (vaild(i-1,j)&&(a[i-1][j]=='W'))
{
if (((i&1))==0) insert_edge(get_id(i-1,j),get_id(i,j),1);
if (((i&1))==1) insert_edge(get_id(i,j)+n*m,get_id(i-1,j)+n*m,1);
}
if (vaild(i+1,j)&&(a[i+1][j]=='W'))
{
if (((i&1))==0) insert_edge(get_id(i+1,j),get_id(i,j),1);
if (((i&1))==1) insert_edge(get_id(i,j)+n*m,get_id(i+1,j)+n*m,1);
}
if (vaild(i,j-1)&&(a[i][j-1]=='W'))
{
if (((i&1))==1) insert_edge(get_id(i,j-1),get_id(i,j),1);
if (((i&1))==0) insert_edge(get_id(i,j)+n*m,get_id(i,j-1)+n*m,1);
}
if (vaild(i,j+1)&&(a[i][j+1]=='W'))
{
if (((i&1))==1) insert_edge(get_id(i,j+1),get_id(i,j),1);
if (((i&1))==0) insert_edge(get_id(i,j)+n*m,get_id(i,j+1)+n*m,1);
}
}
}
}
int ans=2*max_flow(s,t);
if ((ans==sum_w)&&(ans==2*sum_b))
{
puts("YES");
}
else
{
puts("NO");
}
}
return 0;
}
评论 (0)