2017.9.23 循环格 思考记录
2017-09-23 09:26
148 查看
终于不是失败总结了,
这个题其实还是很好分析的,由于每个格子只有一个方向,所以可以考虑每个格子选取唯一的哪个方向
(其实很多网络流的题都隐含1的条件,找到1的条件限制网络流就好想了)
然后就是自带的方向费用是0,修改的方向是1,限制每个点的流入流出,跑完mcmf就是答案了、
码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 15*15*6
#include<queue>
queue<int>q;
int tot=-1,hou[N*4],xia
,zhong[N*4],v[N*4],c[N*4],s,t,n,m,d
,qj
,ans;
bool vis
;
char str;
void jian(int a,int b,int d,int ll)
{
++tot,hou[tot]=xia[a],xia[a]=tot,zhong[tot]=b,c[tot]=d,v[tot]=ll;
}
void jia(int a,int b,int c)
{
jian(a,b,c,1);
jian(b,a,-c,0);
}
bool spfa()
{
int i,j;
q.push(s);
for(i=1;i<=3*n*m;i++)
{
d[i]=1000000009;
}
d[s]=0;
while(!q.empty())
{
int st=q.front();
vis[st]=0;
q.pop();
for(i=xia[st];i!=-1;i=hou[i])
{
int nd=zhong[i];
if(v[i]>0&&d[nd]>d[st]+c[i])
{
d[nd]=d[st]+c[i];
qj[nd]=i^1;
if(vis[nd]==0)
{
vis[nd]=1;
q.push(nd);
}
}
}
}
if(d[t]>1000000007)return 0;
//cout<<d[t]<<endl;
for(i=qj[t];;i=qj[zhong[i]])
{
ans+=c[i^1];
v[i]++;
v[i^1]--;
if(zhong[i]==s)break;
}
return 1;
}
void mcmf()
{
while(spfa());
}
int main()
{
int i,j;
memset(xia,-1,sizeof(xia));
scanf("%d%d",&n,&m);
s=2*n*m+1;
t=2*n*m+2;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
scanf("%c",&str);
while(str!='R'&&str!='L'&&str!='U'&&str!='D') scanf("%c",&str);
int lin;
jia(s,(i-1)*m+j,0);
jia(n*m+(i-1)*m+j,t,0);
if(str=='R')
{
lin=j+1;if(lin>m)lin-=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,0);
lin=j-1;if(lin<=0)lin=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=i-1;
if(lin==0)lin=n;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
lin=i+1;
if(lin>n)lin=1;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
}
if(str=='L')
{
lin=j+1;if(lin>m)lin-=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=j-1;if(lin<=0)lin=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,0);
lin=i-1;
if(lin==0)lin=n;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
lin=i+1;
if(lin>n)lin=1;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
}
if(str=='U')
{
lin=j+1;if(lin>m)lin-=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=j-1;if(lin<=0)lin=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=i-1;
if(lin==0)lin=n;
jia((i-1)*m+j,n*m+(lin-1)*m+j,0);
lin=i+1;
if(lin>n)lin=1;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
}
if(str=='D')
{
lin=j+1;if(lin>m)lin-=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=j-1;if(lin<=0)lin=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=i-1;
if(lin==0)lin=n;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
lin=i+1;
if(lin>n)lin=1;
jia((i-1)*m+j,n*m+(lin-1)*m+j,0);
}
}
mcmf();
printf("%d",ans);
}
这个题其实还是很好分析的,由于每个格子只有一个方向,所以可以考虑每个格子选取唯一的哪个方向
(其实很多网络流的题都隐含1的条件,找到1的条件限制网络流就好想了)
然后就是自带的方向费用是0,修改的方向是1,限制每个点的流入流出,跑完mcmf就是答案了、
码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 15*15*6
#include<queue>
queue<int>q;
int tot=-1,hou[N*4],xia
,zhong[N*4],v[N*4],c[N*4],s,t,n,m,d
,qj
,ans;
bool vis
;
char str;
void jian(int a,int b,int d,int ll)
{
++tot,hou[tot]=xia[a],xia[a]=tot,zhong[tot]=b,c[tot]=d,v[tot]=ll;
}
void jia(int a,int b,int c)
{
jian(a,b,c,1);
jian(b,a,-c,0);
}
bool spfa()
{
int i,j;
q.push(s);
for(i=1;i<=3*n*m;i++)
{
d[i]=1000000009;
}
d[s]=0;
while(!q.empty())
{
int st=q.front();
vis[st]=0;
q.pop();
for(i=xia[st];i!=-1;i=hou[i])
{
int nd=zhong[i];
if(v[i]>0&&d[nd]>d[st]+c[i])
{
d[nd]=d[st]+c[i];
qj[nd]=i^1;
if(vis[nd]==0)
{
vis[nd]=1;
q.push(nd);
}
}
}
}
if(d[t]>1000000007)return 0;
//cout<<d[t]<<endl;
for(i=qj[t];;i=qj[zhong[i]])
{
ans+=c[i^1];
v[i]++;
v[i^1]--;
if(zhong[i]==s)break;
}
return 1;
}
void mcmf()
{
while(spfa());
}
int main()
{
int i,j;
memset(xia,-1,sizeof(xia));
scanf("%d%d",&n,&m);
s=2*n*m+1;
t=2*n*m+2;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
scanf("%c",&str);
while(str!='R'&&str!='L'&&str!='U'&&str!='D') scanf("%c",&str);
int lin;
jia(s,(i-1)*m+j,0);
jia(n*m+(i-1)*m+j,t,0);
if(str=='R')
{
lin=j+1;if(lin>m)lin-=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,0);
lin=j-1;if(lin<=0)lin=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=i-1;
if(lin==0)lin=n;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
lin=i+1;
if(lin>n)lin=1;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
}
if(str=='L')
{
lin=j+1;if(lin>m)lin-=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=j-1;if(lin<=0)lin=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,0);
lin=i-1;
if(lin==0)lin=n;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
lin=i+1;
if(lin>n)lin=1;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
}
if(str=='U')
{
lin=j+1;if(lin>m)lin-=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=j-1;if(lin<=0)lin=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=i-1;
if(lin==0)lin=n;
jia((i-1)*m+j,n*m+(lin-1)*m+j,0);
lin=i+1;
if(lin>n)lin=1;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
}
if(str=='D')
{
lin=j+1;if(lin>m)lin-=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=j-1;if(lin<=0)lin=m;
jia((i-1)*m+j,n*m+(i-1)*m+lin,1);
lin=i-1;
if(lin==0)lin=n;
jia((i-1)*m+j,n*m+(lin-1)*m+j,1);
lin=i+1;
if(lin>n)lin=1;
jia((i-1)*m+j,n*m+(lin-1)*m+j,0);
}
}
mcmf();
printf("%d",ans);
}
相关文章推荐
- 2017.9.23 Count on a tree 思考记录
- 2017.9.14 dispatching 思考记录
- 2017.9.14 棘手的操作 思考记录
- 平日思考小小的记录
- 2017.6.3 完全平方数 思考记录
- 最后登录时间记录的一点思考
- 关于定时器的设计学习记录(学习他人资料)和思考---定时任务 超时控制 频率限制
- 安卓游戏盗取用户 WhatsApp 聊天记录 带给我们的思考!
- VIM 多行输入 数字递增 新方法 循环记录法
- 记录代码——循环移位
- 【蓝桥杯学习记录】【3】递归与循环(3)递归真题
- 实习面试的一个记录及思考
- 2017.8.7 GT考试 思考记录
- 2017.10.25 打鼹鼠 思考记录
- 2017.4.20 火星人 思考记录
- 2017.3.3 拔河比赛 思考记录
- for循环举例_记录
- 以求知心记录,以勤奋心思考,以坦诚心求教,以平常心成长,欢迎大家来指点我成长~
- 2017.4.26 组合数问题 思考记录
- 《不要急于开发要善于思考》---做个记录而已