,你可以沿着箭头防线在格子间行走。即如果(r,c)是一个左箭头,那么走到(r,c-1);如果是右箭头那么走到(r,c+1);如果是上箭头那么走到(r-1,c);如果是下箭头那么走到(r+1,c);每一行和每一列都是循环的,即如果走出边界,你会出现在另一侧。
一个完美的循环格是这样定义的:对于任意一个起始位置,你都可以i沿着箭头最终回到起始位置。如果一个循环格不满足完美,你可以随意修改任意一个元素的箭头直到完美。给定一个循环格,你需要计算最少需要修改多少个元素使其完美。
标签:
,你可以沿着箭头防线在格子间行走。即如果(r,c)是一个左箭头,那么走到(r,c-1);如果是右箭头那么走到(r,c+1);如果是上箭头那么走到(r-1,c);如果是下箭头那么走到(r+1,c);每一行和每一列都是循环的,即如果走出边界,你会出现在另一侧。
一个完美的循环格是这样定义的:对于任意一个起始位置,你都可以i沿着箭头最终回到起始位置。如果一个循环格不满足完美,你可以随意修改任意一个元素的箭头直到完美。给定一个循环格,你需要计算最少需要修改多少个元素使其完美。
第一行两个整数R,C。表示行和列,接下来R行,每行C个字符LRUD,表示左右上下。
一个整数,表示最少需要修改多少个元素使得给定的循环格完美
1<=R,L<=15
解题思路:先建图S向每个点连容量1费用0的边
每个点拆出的点向T连容量1,费用0的边
每个格子向四周连费用0或1的边,然后费用流
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m,len,T,ans,S;
int from[1000001],to[1000001],next[1000001],flow[1000001],w[1000001],h[2000];
bool b[2000];
int dis[2000],q[200000];
int pre[2000];
char c[100];
int u[5][3]={0,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1};
inline int read()
{
char y; int x=0,f=1; y=getchar();
while (y<‘0‘ || y>‘9‘) {if (y==‘-‘) f=-1; y=getchar();}
while (y>=‘0‘ && y<=‘9‘) {x=x*10+int(y)-48; y=getchar();}
return x*f;
}
void insert(int x,int y,int f,int z)
{
++len; from[len]=x; to[len]=y; next[len]=h[x]; h[x]=len; flow[len]=f; w[len]=z;
}
bool spfa()
{
memset(b,true,sizeof(b));
memset(dis,0x7f,sizeof(dis)); dis[S]=0;
int tail=1,head=0; ++tail; q[tail]=S; b[S]=false;
while (head<tail)
{
++head;
int u=h[q[head]];
while (u!=0)
{
if (w[u]+dis[q[head]]<dis[to[u]] && flow[u]>0)
{
dis[to[u]]=dis[q[head]]+w[u];
pre[to[u]]=u;
if (b[to[u]])
{
b[to[u]]=false;
++tail; q[tail]=to[u];
}
}
u=next[u];
}
b[q[head]]=true;
}
if (dis[T]<14000000) return true;else return false;
}
void get()
{
int now=T; int mx=0x7fffffff;
while (now!=S)
{
mx=min(mx,flow[pre[now]]);
now=from[pre[now]];
}
now=T;
while (now!=S)
{
ans+=mx*w[pre[now]];
flow[pre[now]]-=mx; flow[pre[now]^1]+=mx;
now=from[pre[now]];
}
}
int main()
{
len=1; S=0;
n=read(); m=read(); T=n*m*2+1; int opp=n*m;
for (int i=1;i<=n;++i)
{
scanf("%s",c);
for (int j=1;j<=m;++j)
{
int op=(i-1)*m+j; insert(S,op,1,0); insert(op,S,0,0); insert(op+opp,T,1,0); insert(T,op+opp,0,0);
int u1=i;int u2=j;
if (c[j-1]==‘R‘){++u2;}
if (c[j-1]==‘L‘){--u2;}
if (c[j-1]==‘U‘){--u1;}
if (c[j-1]==‘D‘){++u1;}
u1=u1%n; u2=u2%m;
if (u1==0) u1=n; if (u2==0) u2=m;
for (int k=1;k<=4;++k)
{
int x1=(i+u[k][1])%n; int y1=(j+u[k][2])%m;
if (x1==0) x1=n; if (y1==0) y1=m;
int now=(x1-1)*m+y1;
if (x1==u1 && y1==u2)
{
insert(op,now+opp,1,0); insert(now+opp,op,0,0);
}else
{
insert(op,now+opp,1,1); insert(now+opp,op,0,-1);
}
}
}
}
ans=0;
while (spfa())
{
get();
}
printf("%d",ans);
}
标签:
原文地址:http://blog.csdn.net/m_axssi/article/details/51345473