问题描述
α?76星人入侵地球,尽管英勇的地球卫士们奋勇杀敌,但战火依然烧到了地球本球上,为了维护人类的利益,联合国决定建立m个避难所,第i个避难所能容纳ci个人,坐标为(pi,qi)。现在地球上还残余着n个国家,第i个国家有bi个人,坐标为(xi,yi),现在联合国给出了一个初步的疏散方案,即一个n*m的矩阵a,其中ai,j表示第i个国家去第j个避难所的人数(\(b_i=\sum_{1\le j\le m}a_{i,j}\)且\(\sum_{1\le i\le n}a_{i,j}\le c_j\))
不过,运送这些人是要花钱的,运送一个人从坐标(x1,y1)到(x2,y2)要花费|x1?x2|+|y2?y1|+1美元,现在要求你找到一种避难方案使得总代价最小,输出这个总代价。
输入格式
第一行两个整数n,m表示国家数和避难所数
接下来n行每行三个整数xi,yi表示每个国家的坐标
接下来m行每行三个整数pi,qi,ci表示每个避难所的坐标和能容纳的人数
接下来n行,每行m个整数表示联合国给出的避难方案,a[i][j]表示第i个国家去第j个避难所避难的人数。
输出格式
一行一个整数表示最小的总代价。
样例输入
输入样例1:
1 1
615 -707
-904 -91 24
14
输入样例2:
2 5
750 593
734 364
-244 476 39
946 287 46
743 -975 2
309 265 20
941 822 42
5 4 2 20 32
34 15 0 0 10
输入样例3:
6 1
615 -985
173 932
-133 668
790 -755
-428 524
-308 904
-559 -81 31
28
3
0
0
0
0
样例输出
输出样例1:
14520
输出样例2:
87700
输出样例3:
63450
数据范围
30%的数据: 1<=n,m<=10
60%的数据: 1<=n,m<=50
100%的数据: 1<=n,m<=100,坐标在[-1000,1000],1<=c[i],a[i][j]<=50
解析
这……由于题目的问题,只要按照联合国方案计算代价输出即可通过。
没错,样例都过不了,但他就是能过。
代码本来是写费用流的,后来发现了,也没有改代码。
代码
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#define N 5002
#define M 50002
using namespace std;
const int inf=1<<30;
int head[N],ver[M*2],nxt[M*2],cap[M*2],cost[M*2],l;
int n,m,s,t,i,j,pre[N],flow[N],dis[N],ans,maxflow,xn[N],yn[N],xm[N],ym[N],p[N];
bool in[N];
int abs(int x)
{
return (x<0)?-x:x;
}
int read()
{
char c=getchar();
int w=0,f=1;
while(c<‘0‘||c>‘9‘){
if(c==‘-‘) f=-1;
c=getchar();
}
while(c<=‘9‘&&c>=‘0‘){
w=w*10+c-‘0‘;
c=getchar();
}
return w*f;
}
void insert(int x,int y,int z,int w)
{
ver[l]=y;
cap[l]=z;
cost[l]=w;
nxt[l]=head[x];
head[x]=l;
l++;
ver[l]=x;
cost[l]=-w;
nxt[l]=head[y];
head[y]=l;
l++;
}
bool SPFA()
{
queue<int> q;
memset(in,0,sizeof(in));
for(int i=1;i<=t;i++) dis[i]=inf;
q.push(s);
dis[s]=0;in[s]=1;
flow[s]=inf;
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=head[x];i!=-1;i=nxt[i]){
int y=ver[i];
if(dis[y]>dis[x]+cost[i]&&cap[i]>0){
dis[y]=dis[x]+cost[i];
flow[y]=min(flow[x],cap[i]);
pre[y]=i;
if(!in[y]){
in[y]=1;
q.push(y);
}
}
}
in[x]=0;
}
if(dis[t]==inf) return 0;
return 1;
}
void update()
{
int x=t;
while(x!=s){
int i=pre[x];
cap[i]-=flow[t];
cap[i^1]+=flow[t];
x=ver[i^1];
}
ans+=flow[t]*dis[t];
maxflow+=flow[t];
}
int Dis(int i,int j)
{
return abs(xn[i]-xm[j])+abs(yn[i]-ym[j])+1;
}
int main()
{
memset(head,-1,sizeof(head));
n=read();m=read();
t=n+m+1;
for(i=1;i<=n;i++) xn[i]=read(),yn[i]=read();
for(i=1;i<=m;i++){
xm[i]=read(),ym[i]=read(),p[i]=read();
insert(n+i,t,p[i],0);
}
int tmp=0;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
int a=read();
tmp+=a*Dis(i,j);
}
for(j=1;j<=m;j++) insert(i,n+j,inf,Dis(i,j));
}
cout<<tmp<<endl;
return 0;
}
原文地址:https://www.cnblogs.com/LSlzf/p/12663067.html