POJ 2175 Evacuation Plan (费用流,负环,消圈法,SPFA)
http://poj.org/problem?id=2175
|
Evacuation Plan
Description The City has a number of municipal buildings and a number of fallout shelters that were build specially to hide municipal workers in case of a nuclear war. Each fallout shelter has a limited capacityin terms of a number of people it can accommodate, and there's almost no excess capacity in The City's fallout shelters. Ideally, all workers from a given municipal building shall run to the nearest fallout shelter. However, this will lead to overcrowding of some fallout shelters, while others will be half-empty at the same time. To address this problem, The City Council has developed a special evacuation plan. Instead of assigning every worker to a fallout shelter individually (which will be a huge amount of information to keep), they allocated fallout shelters to municipal buildings, listing the number of workers from every building that shall use a given fallout shelter, and left the task of individual assignments to the buildings' management. The plan takes into account a number of workers in every building - all of them are assigned to fallout shelters, and a limited capacity of each fallout shelter - every fallout shelter is assigned to no more workers then it can accommodate, though some fallout shelters may be not used completely. The City Council claims that their evacuation plan is optimal, in the sense that it minimizes the total time to reach fallout shelters for all workers in The City, which is the sum for all workers of the time to go from the worker's municipal building to the fallout shelter assigned to this worker. The City Mayor, well known for his constant confrontation with The City Council, does not buy their claim and hires you as an independent consultant to verify the evacuation plan. Your task is to either ensure that the evacuation plan is indeed optimal, or to prove otherwise by presenting another evacuation plan with the smaller total time to reach fallout shelters, thus clearly exposing The City Council's incompetence. During initial requirements gathering phase of your project, you have found that The City is represented by a rectangular grid. The location of municipal buildings and fallout shelters is specified by two integer numbers and the time to go between municipal building at the location (Xi, Yi) and the fallout shelter at the location (Pj, Qj) is Di,j = |Xi - Pj| + |Yi - Qj| + 1 minutes. Input
The input consists of The City description and the evacuation plan description. The first line of the input file consists of two numbers N and M separated by a space. N (1 ≤ N ≤ 100) is a number of municipal buildings in The City (all municipal buildings are
numbered from 1 to N). M (1 ≤ M ≤ 100) is a number of fallout shelters in The City (all fallout shelters are numbered from 1 to M). The following N lines describe municipal buildings. Each line contains there integer numbers Xi, Yi, and Bi separated by spaces, where Xi, Yi (-1000 ≤ Xi, Yi ≤ 1000) are the coordinates of the building, and Bi (1 ≤ Bi ≤ 1000) is the number of workers in this building. The description of municipal buildings is followed by M lines that describe fallout shelters. Each line contains three integer numbers Pj, Qj, and Cj separated by spaces, where Pi, Qi (-1000 ≤ Pj, Qj ≤ 1000) are the coordinates of the fallout shelter, and Cj (1 ≤ Cj ≤ 1000) is the capacity of this shelter. The description of The City Council's evacuation plan follows on the next N lines. Each line represents an evacuation plan for a single building (in the order they are given in The City description). The evacuation plan of ith municipal building consists of M integer numbers Ei,j separated by spaces. Ei,j (0 ≤ Ei,j ≤ 1000) is a number of workers that shall evacuate from the ith municipal building to the jth fallout shelter. The plan in the input file is guaranteed to be valid. Namely, it calls for an evacuation of the exact number of workers that are actually working in any given municipal building according to The City description and does not exceed the capacity of any given fallout shelter. Output
If The City Council's plan is optimal, then write to the output the single word OPTIMAL. Otherwise, write the word SUBOPTIMAL on the first line, followed by N lines that describe your plan in the same format as in the input file. Your plan need not be optimal
itself, but must be valid and better than The City Council's one. Sample Input 3 4 Sample Output SUBOPTIMAL Source |
||||||||||
题意:
有N幢楼,M个避难所。给出坐标,楼中人数及避难所容量,每人从楼到避难所的花费是曼哈顿距离+1。
现给出一种避难方案,推断是否是最优的(全部人的花费之和最小),假设不是,给出一种更优的方案。
分析:
非常easy想到是费用流。
源点到楼连边。容量为楼中人数。单位流量费用为0;避难所到汇点连边,容量为避难所容量。单位流量费用为0;楼到避难所连边,容量为无穷大,单位流量费用为曼哈顿距离+1。
在此图中跑一遍最小费用最大流,假设最小费用比给出的方案费用小,则相应的流的方案更优(且是最优的)。
上述思路尽管没错,但非常不幸,效率非常低,我毫无疑问地获得了TLE。那么有没有更好的算法呢?
按最小费用最大流跑出的流相应最优的方案,那么已经给出的方案显然相应某个最大流,题目要求推断给出的方案是否是最优的<=>该流的费用最小。假设某流f是最小费用流<=>残留网络中没有负圈。假设有负圈。则沿着该负圈增广。就能得到同样流量下费用更小的流。推断负圈仅仅要用SPFA,在实际測试中,用栈比队列推断负圈效率更高。值得注意的是,假设某个点进栈/队N次(假设一共N个点)。那么图中存在负环,可是这个点却未必在负环中(是不是非常惊悚?)。仅仅能说这个点被负环更新过。即负环在这个点之前,所以我们仅仅要从这个点往前找到负环。然后在负环中增广,就可以获得费用更小的流。
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<cctype>
#include<cmath>
#include<string>
#include<cstring>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<map>
#include<set>
#define sqr(x) ((x)*(x))
#define LL long long
#define itn int
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
#define eps 1e-10
#define maxm (65536)
#define maxn (202) using namespace std; struct __point
{
int x,y,p;
}b[101],sh[101];
int n,m; int fir[maxn];
int u[maxm],v[maxm],cap[maxm],flow[maxm],cost[maxm],nex[maxm];
int e_max;
int q[maxn],d[maxn],prev[maxn],cnt[maxn];
bool inq[maxn]; int G[101][101];
int shelter[101];
bool vis[maxn]; void add_edge(int _u,int _v,int _cap,int _cost,int _f)
{
int e;
e=e_max++;
u[e]=_u;v[e]=_v;cap[e]=_cap;cost[e]=_cost;flow[e]=_f;
nex[e]=fir[u[e]];fir[u[e]]=e;
e=e_max++;
u[e]=_v;v[e]=_u;cap[e]=0;cost[e]=-_cost;flow[e]=-_f;
nex[e]=fir[u[e]];fir[u[e]]=e;
} int negative_loop(int s,int t)
{
int f,r,top=-1;
f=0;r=-1; memset(cnt,0,sizeof cnt);
memset(d,0,sizeof d);
memset(inq,1,sizeof inq);//inq是bool类型的数组,每一个元素占1字节,所以能够这样
memset(prev,-1,sizeof prev);
for (int i=s;i<=t;i++)
q[++r]=i; while (f<=r)
{
int x=q[r--];//栈式写法。r--改成f++就是队列了。队列要将数组扩大。
inq[x]=false;
for (int e=fir[x];~e;e=nex[e])
{
if (cap[e]>flow[e] && d[v[e]]>d[u[e]]+cost[e])
{
d[v[e]]=d[u[e]]+cost[e];
prev[v[e]]=e;
if (!inq[v[e]])
{
q[++r]=v[e];
inq[v[e]]=true;
cnt[v[e]]++;
if (cnt[v[e]]>t-s+1) return v[e];
//如过不想推断边界。就把这个值调大些,由于假设没有负环就不会进队/栈那么多次,假设有负环,就会无限循环下去
}
}
}
} return -1;
} inline int __cost(const __point &p1,const __point &p2)
{
return abs(p1.x-p2.x)+abs(p1.y-p2.y)+1;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("/home/fcbruce/文档/code/t","r",stdin);
#endif // ONLINE_JUDGE int p;
int s,t;
scanf("%d%d",&n,&m);
s=0;t=n+m+1;
e_max=0;
memset(fir,-1,sizeof fir); for (int i=0;i<n;i++)
{
scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].p);
add_edge(s,i+1,b[i].p,0,b[i].p);
} for (int i=0;i<m;i++)
{
scanf("%d%d%d",&sh[i].x,&sh[i].y,&sh[i].p);
} memset(shelter,0,sizeof shelter);
for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
scanf("%d",&p);
shelter[j]+=p;
add_edge(i+1,n+j+1,INF,__cost(b[i],sh[j]),p);
}
} for (int i=0;i<m;i++)
{
add_edge(i+1+n,t,sh[i].p,0,shelter[i]);
} int k=negative_loop(s,t); if (k!=-1)
{
puts("SUBOPTIMAL");
memset(vis,0,sizeof vis); for (int e=prev[k];!vis[v[e]];e=prev[u[e]])//往前找负环
{
vis[v[e]]=true;
k=v[e];
} for (int e=prev[k];;e=prev[u[e]])//在负环中增广
{
flow[e]++;//仅仅要找一个更优的解。+1即可
flow[e^1]--;
if (u[e]==k)break;
} for (int e=0;e<e_max;e++)
{
if (u[e]>0 && u[e]<=n && v[e]>n && v[e]<=n+m)
G[u[e]-1][v[e]-n-1]=flow[e];
} for (int i=0;i<n;i++)
{
for (int j=0;j<m;j++)
{
if (j) putchar(' ');
printf("%d",G[i][j]);
}
putchar('\n');
}
}
else
puts("OPTIMAL"); return 0;
}
POJ 2175 Evacuation Plan (费用流,负环,消圈法,SPFA)的更多相关文章
- POJ 2175 Evacuation Plan 费用流 负圈定理
题目给了一个满足最大流的残量网络,判断是否费用最小. 如果残量网络中存在费用负圈,那么不是最优,在这个圈上增广,增广1的流量就行了. 1.SPFA中某个点入队超过n次,说明存在负环,但是这个点不一定在 ...
- POJ 2175 Evacuation Plan
Evacuation Plan Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Origina ...
- POJ.2175.Evacuation Plan(消圈)
POJ \(Description\) \(n\)个建筑物,每个建筑物里有\(a_i\)个人:\(m\)个避难所,每个避难所可以容纳\(b_i\)个人. 给出每个建筑物及避难所的坐标,任意两点间的距离 ...
- POJ-2175 Evacuation Plan 最小费用流、负环判定
题意:给定一个最小费用流的模型,根据给定的数据判定是否为最优解,如果不为最优解则给出一个比给定更优的解即可.不需要得出最优解. 解法:由给定的数据能够得出一个残图,且这个图满足了最大流的性质,判定一个 ...
- Codeforces Gym 100002 E "Evacuation Plan" 费用流
"Evacuation Plan" Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10 ...
- POJ - 2175 Evacuation Plan (最小费用流消圈)
题意:有N栋楼,每栋楼有\(val_i\)个人要避难,现在有M个避难所,每个避难所的容量为\(cap_i\),每个人从楼i到避难所j的话费是两者的曼哈顿距离.现在给出解决方案,问这个解决方案是否是花费 ...
- 最小费用流判负环消圈算法(poj2175)
Evacuation Plan Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3384 Accepted: 888 ...
- POJ 3680 Intervals(费用流+负权优化)
[题目链接] http://poj.org/problem?id=3680 [题目大意] 有N个带权重的区间,现在要从中选取一些区间, 要求任意点都不被超过K个区间所覆盖,请最大化总的区间权重. [题 ...
- poj 2175 Evacuation Plan 最小费用流判定,消圈算法
题目链接 题意:一个城市有n座行政楼和m座避难所,现发生核战,要求将避难所中的人员全部安置到避难所中,每个人转移的费用为两座楼之间的曼哈顿距离+1,题目给了一种方案,问是否为最优方案,即是否全部的人员 ...
随机推荐
- MVC验证码的编写
主要是相互学习一下mvc,希望各位大神指导 /// <summary> /// 生成随机数字 /// </summary> /// <returns>随机数字< ...
- apache 2.4 You don't have permission to access / on this server
用的2.4版本,以前版本解决: 马上打开apache的配置文件httpd.conf,逐行检查.在大约快一半的地方有以下这段代码: <Directory /> Options Foll ...
- 浅谈PHP代码设计结构
浅谈PHP代码设计结构 您的评价: 还行 收藏该经验 coding多年,各种代码日夜相伴,如何跟代码友好的相处,不光成为职业生涯的一种回应,也是编写者功力的直接显露. 如何看 ...
- C# 连接SQL数据库
感觉很有必要总结一下 一:C# 连接SQL数据库 Data Source=myServerAddress;Initial Catalog=myDataBase;User Id=myUsername;P ...
- IP V4地址分类
IP V4地址 共分为五类: A类地址范围:1.0.0.1---126.255.255.254 B类地址范围:128.0.0.1---191.255.255.254 C类地址范围:192.0.0.1- ...
- spark 操作hbase
HBase经过七年发展,终于在今年2月底,发布了 1.0.0 版本.这个版本提供了一些让人激动的功能,并且,在不牺牲稳定性的前提下,引入了新的API.虽然 1.0.0 兼容旧版本的 API,不过还是应 ...
- angularjs自定义日期过滤器,如:周日(前天 21:24)
今天给大家分享一个,我在项目中自定义的一个日期过滤器.具体过滤出来的效果可参看下图: 用法: {{ time | timeFilter }} filter: App.filter('timeFilte ...
- 微软SpeechRecognitionEngine
API官网手册:http://msdn.microsoft.com/zh-cn/library/System.Speech.Recognition.SpeechRecognitionEngine(v= ...
- mysql 索引管理原则
最近在学习mysql的索引优化,结合着我们网盟系统的一些业务,翻阅一些资料,整理出如下的一些想法: 1.索引建立的原则一:最左前缀匹配原则 ,非常重要的原则,mysql会一直向右匹配直到遇到范围查询( ...
- Android开发者须知的几种APP加密方式--备
作为一个Android开发者,不仅需要使自己的APP功能丰富,便于使用,同时也需要去完善APP的安全性,下面就介绍几种简单而又可靠的加密方法.1.Spongy Castle Spongy Castle ...
The City has a number of municipal buildings and a number of fallout shelters that were build specially to hide municipal workers in case of a nuclear war. Each fallout shelter has a limited capacity