【codevs2440】【BZOJ1066】蜥蜴,最大流
2016-05-29 08:05
309 查看
Time:2016.05.29
Author:xiaoyimi
转载注明出处谢谢
思路:
(水题硬是让我调了1h+)
a[i][j]为第i行第j列的石柱高度
把每个石柱i拆成两个点pi,qi,连边流量为a[i][j],如果上面有蜥蜴就连一条s到pi的点,流量为1,如果i能跳出边界,就连一条qi到t的边,流量inf,然后qi向所有能到达的石柱pj连边(不能向自己连边),流量为inf。跑出来的最大流就是能跑出去的蜥蜴的最大数量
注意:
(为了图省事边读入边连边,结果调了好久)
代码:
Author:xiaoyimi
转载注明出处谢谢
思路:
(水题硬是让我调了1h+)
a[i][j]为第i行第j列的石柱高度
把每个石柱i拆成两个点pi,qi,连边流量为a[i][j],如果上面有蜥蜴就连一条s到pi的点,流量为1,如果i能跳出边界,就连一条qi到t的边,流量inf,然后qi向所有能到达的石柱pj连边(不能向自己连边),流量为inf。跑出来的最大流就是能跑出去的蜥蜴的最大数量
注意:
(为了图省事边读入边连边,结果调了好久)
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<queue> #define inf 100000 using namespace std; int n,m,d,tot=1,s,t; int a[22][22],dis[1000],first[1000]; bool b[22][22]; struct edge{int v,w,next;}e[500010]; queue<int>q; void add(int x,int y,int z) { e[++tot]=(edge){y,z,first[x]};first[x]=tot; e[++tot]=(edge){x,0,first[y]};first[y]=tot; } bool bfs() { memset(dis,0,sizeof(dis)); q.push(s);dis[s]=1; while (!q.empty()) { int k=q.front();q.pop(); for (int i=first[k];i;i=e[i].next) if (e[i].w&&!dis[e[i].v]) dis[e[i].v]=dis[k]+1, q.push(e[i].v); } return dis[t]; } int dfs(int x,int maxn) { if (x==t) return maxn; int used=0; for (int i=first[x];i;i=e[i].next) if (dis[e[i].v]==dis[x]+1) { int k=dfs(e[i].v,min(maxn-used,e[i].w)); used+=k; e[i].w-=k;e[i^1].w+=k; if (used==maxn) return maxn; } if (!used) dis[x]=0; return used; } bool cal(int x1,int y1,int x2,int y2){return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)<=d*d;} main() { scanf("%d%d%d",&n,&m,&d); t=n*m*2+1; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { char ch=getchar(); while (ch>'3'||ch<'0') ch=getchar(); a[i][j]=ch-'0'; } for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (a[i][j]) { add((i-1)*m+j,(i-1)*m+j+n*m,a[i][j]); if (d>=min(min(i,j),min(n-i+1,m-j+1))) add((i-1)*m+j+n*m,t,a[i][j]); for (int p=1;p<=n;p++) for (int q=1;q<=m;q++) if (a[p][q]&&(p!=i||q!=j)&&cal(i,j,p,q)) add((i-1)*m+j+n*m,(p-1)*m+q,a[i][j]); } int ans=0; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { char ch=getchar(); while (ch!='.'&&ch!='L') ch=getchar(); b[i][j]=(ch=='L'); if (b[i][j]) ans++,add(s,(i-1)*m+j,1); } while (bfs()) ans-=dfs(s,inf); printf("%d",ans); }
相关文章推荐
- 线程安全和线程不安全
- Java桥模式(Bridge模式)
- Java共享模式/享元模式(Flyweight模式)
- Java原型模式(Prototype模式)
- Java建造者模式(Builder模式)
- PhoneGap android开发:Notification
- Java单态模式(Singleton模式)
- dubbo源码分析系列——项目工程结构介绍
- C++ STL 的实现
- HDU1863畅通工程---并查集+最小生成树
- Java工厂模式(Factory模式)
- PhoneGap android开发:GPS定位
- JetBrains PhpStorm/WebStorm/PyCharm 注册码
- java入门教程-12.10Java数据库之删除记录
- 第13周学习进度条
- java入门教程-12.9Java数据库之修改记录
- java入门教程-12.8Java数据库之插入记录
- Java抽象类继承问题
- java入门教程-12.7Java数据库更新
- java入门教程-12.6Java数据库查询简介