POJ.2175.Evacuation Plan(消圈)
\(Description\)
\(n\)个建筑物,每个建筑物里有\(a_i\)个人;\(m\)个避难所,每个避难所可以容纳\(b_i\)个人。
给出每个建筑物及避难所的坐标,任意两点间的距离为它们的曼哈顿距离\(+1\)。
现在给出一个分配方案(\(g[i][j]\)表示第\(i\)个建筑物去第\(j\)个避难所的人数),问是否存在所有人移动的距离之和比当前更小的方案。如果存在,输出任意一组更小的方案。
\(n,m\leq100\)
\(Solution\)
直接跑费用流会T,但是也没必要。
如果残量网络存在负环(只走有流量的边),那么沿该负环继续增广,可以得到一组更优的解。否则就是当前流量下的最小费用流。
所以建出残量网络,找出负环来,在负环上走一遍就行了。
\(S\to i\)的每条边的流量肯定是流满的,所以不需要建(\(i'\to T\)的就不一定了)。
复杂度\(O(nm)\)。(\(m\)是边数)
//688K 329MS
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=205,M=(105*105+N)*2,INF=0x3f3f3f3f;
int Enum,H[N],nxt[M],to[M],cost[M],dis[N],pre[N],g[105][105];
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now*f;
}
inline void AE(int u,int v,int w,int c)
{
if(w) to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, cost[Enum]=c;
}
int SPFA(const int n)
{
static int tm[N];
static bool inq[N];
std::queue<int> q;
memset(dis,0x3f,n+1<<2);
dis[n]=0, q.push(n), tm[n]=1;
while(!q.empty())
{
int x=q.front(); q.pop();
inq[x]=0;
for(int i=H[x],v; i; i=nxt[i])
if(dis[to[i]]>dis[x]+cost[i])
{
dis[v=to[i]]=dis[x]+cost[i], pre[v]=x;
if(!inq[v])
{
if(++tm[v]>=n) return v;
q.push(v), inq[v]=1;
}
}
}
return -1;
}
void FindCircle(int x,const int n)
{
static bool vis[N];
while(!vis[x]) vis[x]=1, x=pre[x];//p不一定在环上(但是能回到环),应该先找出来啊。。
int tmp=x;
do
{
int v=pre[x];//v->x
if(x<=n && v>n) --g[x][v-n];
else if(x>n && v<=n) ++g[v][x-n];
x=v;
}while(x!=tmp);
}
int main()
{
static int a[N],b[N],c[N],d[N],cap[N],use[N];
const int n=read(),m=read(),T=n+m+1;
for(int i=1; i<=n; ++i) a[i]=read(),b[i]=read(),read();
for(int i=1; i<=m; ++i) c[i]=read(),d[i]=read(),cap[i]=read();
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
{
use[j]+=g[i][j]=read();
int cost=std::abs(a[i]-c[j])+std::abs(b[i]-d[j])+1;
AE(i,j+n,INF-g[i][j],cost), AE(j+n,i,g[i][j],-cost);//negative!
}
for(int i=1; i<=m; ++i) AE(i+n,T,cap[i]-use[i],0), AE(T,i+n,use[i],0);
int p=SPFA(T);
if(p==-1) puts("OPTIMAL");
else
{
FindCircle(p,n), puts("SUBOPTIMAL");
for(int i=1; i<=n; ++i,putchar('\n'))
for(int j=1; j<=m; ++j) printf("%d ",g[i][j]);
}
return 0;
}
POJ.2175.Evacuation Plan(消圈)的更多相关文章
- POJ 2175 Evacuation Plan (费用流,负环,消圈法,SPFA)
http://poj.org/problem?id=2175 Evacuation Plan Time Limit: 1000MS Memory Limit: 65536K Total Submi ...
- POJ 2175 Evacuation Plan
Evacuation Plan Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Origina ...
- poj 2175 Evacuation Plan 最小费用流判定,消圈算法
题目链接 题意:一个城市有n座行政楼和m座避难所,现发生核战,要求将避难所中的人员全部安置到避难所中,每个人转移的费用为两座楼之间的曼哈顿距离+1,题目给了一种方案,问是否为最优方案,即是否全部的人员 ...
- POJ - 2175 Evacuation Plan (最小费用流消圈)
题意:有N栋楼,每栋楼有\(val_i\)个人要避难,现在有M个避难所,每个避难所的容量为\(cap_i\),每个人从楼i到避难所j的话费是两者的曼哈顿距离.现在给出解决方案,问这个解决方案是否是花费 ...
- POJ 2175 Evacuation Plan 费用流 负圈定理
题目给了一个满足最大流的残量网络,判断是否费用最小. 如果残量网络中存在费用负圈,那么不是最优,在这个圈上增广,增广1的流量就行了. 1.SPFA中某个点入队超过n次,说明存在负环,但是这个点不一定在 ...
- poj 2175 费用流消圈
题意抽象出来就是给了一个费用流的残存网络,判断该方案是不是最优方案,如果不是,还要求给出一个更优方案. 在给定残存网络上检查是否存在负环即可判断是否最优. 沿负环增广一轮即可得到更优方案. 考虑到制作 ...
- POJ 2157 Evacuation Plan [最小费用最大流][消圈算法]
---恢复内容开始--- 题意略. 这题在poj直接求最小费用会超时,但是题意也没说要求最优解. 根据线圈定理,如果一个跑完最费用流的残余网络中存在负权环,那么顺着这个负权环跑流量为1那么会得到更小的 ...
- POJ 2175:Evacuation Plan(费用流消圈算法)***
http://poj.org/problem?id=2175 题意:有n个楼,m个防空洞,每个楼有一个坐标和一个人数B,每个防空洞有一个坐标和容纳量C,从楼到防空洞需要的时间是其曼哈顿距离+1,现在给 ...
- POJ2175:Evacuation Plan(消负圈)
Evacuation Plan Time Limit: 1000MSMemory Limit: 65536KTotal Submissions: 5665Accepted: 1481Special J ...
随机推荐
- UEFI rootkit 工具LoJax可以感染电脑主板(mainboard)
1.UEFI(Unified Extensible Firmware Interface)统一扩展接口,UEFI rootkit是以在UEFI中植入rootkit ,18年9月份ESET首次公开了境外 ...
- poj3417lca+树上差分
/* 给定n个点的树,在其中加入m条新边(称为非树边) 现在可以割断一条树边,一条非树边,使图分裂成两个联通块,请问有几种切割方式 对树边进行分情况讨论 如果树边不处在环中,则割断这条树边后可以割断任 ...
- bzoj2200拓扑排序+最短路+联通块
自己写的不知道哪里wa了,明明和网上的代码差不多.,. /* 给定一张图,有的边是无向边,有的是有向边,有向边不会出现在环中,且有可能是负权值 现在给定起点s,求出s到其余所有点的最短路长度 任何存在 ...
- 论文阅读笔记二十八:You Only Look Once: Unified,Real-Time Object Detection(YOLO v1 CVPR2015)
论文源址:https://arxiv.org/abs/1506.02640 tensorflow代码:https://github.com/nilboy/tensorflow-yolo 摘要 该文提出 ...
- Android 网络请求框架
1.okHttp 特点 简单.灵活.无连接.无状态 优势: 谷歌官方API在6.0之后在Android SDK中移除了HttpClient,然后他火了起来, 他支持SPDY(谷歌开发的基于TCP应用层 ...
- hdfs数据到hive中,以及hdfs数据隐身理解
hdfs数据到hive中: 假设hdfs中已存在好了数据,路径是hdfs:/localhost:9000/user/user_w/hive_g2park/user_center_enterprise_ ...
- 史上最简单的SpringCloud教程 | 第七篇: 高可用的分布式配置中心(Spring Cloud Config)
上一篇文章讲述了一个服务如何从配置中心读取文件,配置中心如何从远程git读取配置文件,当服务实例很多时,都从配置中心读取文件,这时可以考虑将配置中心做成一个微服务,将其集群化,从而达到高可用,架构图如 ...
- 最短路径问题---Dijkstra算法详解
侵删https://blog.csdn.net/qq_35644234/article/details/60870719 前言 Nobody can go back and start a new b ...
- 微信小程序 this和that详解及简单实例
微信小程序中,在wx.request({});方法调用成功或者失败之后,有时候会需要获取页面初始化数据data的情况,这个时候,如果使用,this.data来获取,会出现获取不到的情况,调试页面也会报 ...
- TodoMVC:帮助你选择一个MV*框架
开发者现在有很多的MV*框架选择来组织开发web应用程序.Backbone. Ember.AngularJS.Spine… 新的稳定解决方案列表持续增长,但你如何决定在海量的框架中选择哪个使用? 为了 ...