您的位置:首页 > 其它

[费用流]BZOJ:3171: [Tjoi2013]循环格

2014-02-28 10:58 239 查看

3171: [Tjoi2013]循环格

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 258  Solved: 153

[Submit][Status]


Description




Input

第一行两个整数R,C。表示行和列,接下来R行,每行C个字符LRUD,表示左右上下。


Output

 
一个整数,表示最少需要修改多少个元素使得给定的循环格完美


Sample Input

3 4

RRRD

URLL

LRRR


Sample Output

2


HINT

1<=R,L<=15


Source

首先,我们可以推断出来:构成循环格的条件是每个格子入度出度都是1
那么我们可以构造一个类似二分图的图,左边右边点相同,如果i可以指到j,左i到右j连一条边
这样每个格子都有一个入边和出边了
然后是费用的问题,如果存在边(左i,右j)如果i原本就指向j,则cost[i][j]=0,否则为1
然后求最小费用最大流
/**************************************************************
Problem: 3171
User: SKYDEC
Language: C++
Result: Accepted
Time:268 ms
Memory:4712 kb
****************************************************************/

#include<stdio.h>
#define f(i,j) ((i)-1)*c+(j)
#define debug printf("yeah!")
using namespace std;
bool create[800][800];
long cost[800][800];
long pre[500];long r,c,s,t;
long que[100000],k[100000];
int spfa()
{
pre[t]=-1;bool gone[500]={false};que[0]=1;que[1]=s;gone[s]=true;long dis[800];for(long i=s;i<=t;i++)dis[i]=2100000000;
dis[0]=0;
while(que[0]!=0)
{
k[0]=0;
for(long i=1;i<=que[0];i++)
{
long cur=que[i];
for(long j=s;j<=t;j++)
if(create[cur][j]&&(dis[cur]+cost[cur][j]<dis[j]))
{
dis[j]=dis[cur]+cost[cur][j];pre[j]=cur;
if(!gone[j]){k[++k[0]]=j;gone[j]=true;}
}
gone[cur]=false;
}
que[0]=k[0];for(long u=1;u<=que[0];u++)que[u]=k[u];
}
return pre[t];
}
int main()
{
//freopen("grid.in","r",stdin);freopen("grid.out","w",stdout);
scanf("%ld%ld",&r,&c);s=0;t=2*r*c+1;char goe;scanf("%c",&goe);
for(long i=1;i<=r;i++)for(long j=1;j<=c;j++)
{
create[s][f(i,j)]=true;create[f(i,j)+r*c][t]=true;
create[f(i,j)][f(i,j%c+1)+r*c]=true;
cost[f(i,j)][f(i,j%c+1)+r*c]=1;
cost[f(i,j%c+1)+r*c][f(i,j)]=-1;
create[f(i,j)][f(i%r+1,j)+r*c]=true;
cost[f(i,j)][f(i%r+1,j)+r*c]=1;
cost[f(i%r+1,j)+r*c][f(i,j)]=-1;
long ti=i,tj=j;if(i==1)ti=r;else ti--;
create[f(i,j)][f(ti,tj)+r*c]=true;
cost[f(i,j)][f(ti,tj)+r*c]=1;
cost[f(ti,tj)+r*c][f(i,j)]=-1;
ti=i;tj=j;if(j==1)tj=c;else tj--;
create[f(i,j)][f(ti,tj)+r*c]=true;
cost[f(i,j)][f(ti,tj)+r*c]=1;
cost[f(ti,tj)+r*c][f(i,j)]=-1;
}
for(long i=1;i<=r;i++)
{
for(long j=1;j<=c;j++)
{
char u;scanf("%c",&u);
if(u=='R')cost[f(i,j)][f(i,j%c+1)+r*c]=cost[f(i,j%c+1)+r*c][f(i,j)]=0;
if(u=='D')cost[f(i,j)][f(i%r+1,j)+r*c]=cost[f(i%r+1,j)+r*c][f(i,j)]=0;
if(u=='U')
{
long ti=i,tj=j;if(i==1)ti=r;else ti--;
cost[f(i,j)][f(ti,tj)+r*c]=cost[f(ti,tj)+r*c][f(i,j)]=0;
}
if(u=='L')
{
long ti=i,tj=j;if(j==1)tj=c;else tj--;
cost[f(i,j)][f(ti,tj)+r*c]=cost[f(ti,tj)+r*c][f(i,j)]=0;
}
}
while(true)
{
scanf("%c",&goe);
if(goe=='\n')break;
}
}
long long ans=0;
while(spfa()!=-1)
{
long p=t;
while(p!=s)
{
ans+=cost[pre[p]][p];
create[pre[p]][p]=false;
create[p][pre[p]]=true;
p=pre[p];
}
}
printf("%lld",ans);
//for(;;);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: