其他分享
首页 > 其他分享> > [51nod] 2982 大逃杀

[51nod] 2982 大逃杀

作者:互联网

问题描述

α−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 <cstring>
#include <queue>
#define N 1000002
#define M 1000002
using namespace std;
const int inf=1<<30;
int head[N],ver[M*2],nxt[M*2],cap[M*2],l;
int n,m,s,t,i,dis[N],ans;
int read()
{
	char c=getchar();
	int w=0;
	while(c<'0'||c>'9') c=getchar();
	while(c<='9'&&c>='0'){
		w=w*10+c-'0';
		c=getchar();
	}
	return w;
}
void insert(int x,int y,int z)
{
	ver[l]=y;
	cap[l]=z;
	nxt[l]=head[x];
	head[x]=l;
	l++;
	ver[l]=x;
	nxt[l]=head[y];
	head[y]=l;
	l++;
}
bool bfs()
{
	queue<int> q;
	memset(dis,-1,sizeof(dis));
	q.push(s);
	dis[s]=0;
	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]==-1&&cap[i]>0){
				dis[y]=dis[x]+1;
				q.push(y);
			}
		}
	}
	return (dis[t]!=-1);
}
int dfs(int x,int flow)
{
	if(x==t||flow==0) return flow;
	int ans=0;
	for(int i=head[x];i!=-1;i=nxt[i]){
		int y=ver[i];
		if(dis[y]==dis[x]+1&&cap[i]>0){
			int a=dfs(y,min(flow,cap[i]));
			flow-=a;
			ans+=a;
			cap[i]-=a;
			cap[i^1]+=a;
		}
		if(flow==0) break;
	}
	if(flow) dis[x]=-1;
	return ans;
}
int main()
{
	memset(head,-1,sizeof(head));
	n=read();m=read();
	t=n+2*m+1;
	for(i=2;i<n;i++){
		int va=read();
		insert(s,i,va);
		ans+=va;
	}
	for(i=2;i<n;i++){
		int vb=read();
		insert(i,t,vb);
		ans+=vb;
	}
	insert(s,1,inf);
	insert(n,t,inf);
	for(i=1;i<=m;i++){
		int u=read(),v=read(),ea=read(),eb=read(),ec=read();
		insert(u,v,ec);insert(v,u,ec);
		insert(s,n+i,ea);insert(n+i,u,inf);insert(n+i,v,inf);
		insert(n+m+i,t,eb);insert(u,n+m+i,inf);insert(v,n+m+i,inf);
		ans+=ea+eb;
	}
	while(bfs()) ans-=dfs(s,inf);
	printf("%d\n",ans);
	return 0;
}

标签:大逃杀,head,51nod,2982,cap,样例,flow,int,dis
来源: https://www.cnblogs.com/LSlzf/p/12663067.html