bzoj 1061

1061: [Noi2008]志愿者招募

Description

  申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管。布布刚上任就遇到了一个难
题:为即将启动的奥运新项目招募一批短期志愿者。经过估算,这个项目需要N 天才能完成,其中第i 天至少需要
Ai 个人。 布布通过了解得知,一共有M 类志愿者可以招募。其中第i 类可以从第Si 天工作到第Ti 天,招募费用
是每人Ci 元。新官上任三把火,为了出色地完成自己的工作,布布希望用尽量少的费用招募足够的志愿者,但这
并不是他的特长!于是布布找到了你,希望你帮他设计一种最优的招募方案。

Input

  第一行包含两个整数N, M,表示完成项目的天数和可以招募的志愿者的种类。 接下来的一行中包含N 个非负
整数,表示每天至少需要的志愿者人数。 接下来的M 行中每行包含三个整数Si, Ti, Ci,含义如上文所述。为了
方便起见,我们可以认为每类志愿者的数量都是无限多的。

Output

  仅包含一个整数,表示你所设计的最优方案的总费用。

Sample Input

3 3
2 3 4
1 2 2
2 3 5
3 3 2

Sample Output

14

HINT

1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,题目中其他所涉及的数据均 不超过2^31-1。


确实,只有这里有比较详细的解释了
蒟蒻的网络流很垃圾。。于是看了好一会


因为我们知道网络流肯定都是流量平衡的,所以只要最大流量了,那么肯定就能满足所有的等式------也就是能把所有的常数项满足,就满足条件了
但似乎题目也没有无解的数据,要不他的答案就错了(反正无解也没有答案)
贴一下代码 (很多都是抄的):
#include<cstdio>
#include<cstring>
const int N=1005;
const int MAX=1<<30;
int n,m;
int st1,ed1;
struct qq
{
	int x,y;
	int last;
	int z,z1,other;
}s[50005];
int num,last[N];
int ans=0;
int init1 (int x,int y,int z,int z1)
{
	num++;
	s[num].x=x;s[num].y=y;s[num].z=z;s[num].z1=z1;
	s[num].last=last[x];
	last[x]=num;
	return num;
}
void init (int x,int y,int z,int z1)
{
	int num1=init1(x,y,z,z1),num2=init1(y,x,0,-z1);
	s[num1].other=num2;s[num2].other=num1;
	return ;
}
int dis[N],from[N],q[N];
bool q1[N];
bool SPFA ()
{
	memset(dis,127,sizeof(dis));
	memset(from,-1,sizeof(from));
	memset(q1,false,sizeof(q1));
	int st=1,ed=2;
	dis[st1]=0;from[st1]=-1;q1[st1]=true;q[st]=st1;
	while (st!=ed)
	{
		int x=q[st];
		for (int u=last[x];u!=-1;u=s[u].last)
		{
			int y=s[u].y;
			if (s[u].z>0&&dis[x]+s[u].z1<dis[y])
			{
				from[y]=u;
				dis[y]=dis[x]+s[u].z1;
				if (q1[y]==false)
				{
					q1[y]=true;
					q[ed]=y;
					ed++;
					if (ed>=N-1) ed=1;
				}
			}
		}
		q1[x]=false;
		st++;
		if (st>=N-1) st=1;
	}
	if (from[ed1]!=-1) return true;
	return false;
}
int mymin (int x,int y)
{
	return x<y?x:y;
}
void add ()
{
	int x=from[ed1];
	int f=MAX;
	while (x!=-1)
	{
		f=mymin(f,s[x].z);
		x=from[s[x].x];
	}
	x=from[ed1];
	while (x!=-1)
	{
		ans=ans+f*s[x].z1;
		s[x].z-=f;
		s[s[x].other].z+=f;
		x=from[s[x].x];
	}
}
int main()
{
	num=0;memset(last,-1,sizeof(last));
	st1=1003;ed1=st1+1;
	int l=0;
	scanf("%d%d",&n,&m);
	for (int u=1;u<=n;u++)
	{
		int x,a;
		scanf("%d",&a);
		x=a-l;l=a;
		if (x>0) init(st1,u,x,0);
		else init(u,ed1,-x,0);//常数 
		init(u+1,u,MAX,0);//Y值
	}
	init(n+1,ed1,l,0);
	for (int u=1;u<=m;u++)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		init(x,y+1,MAX,z);//X值
	}
	while (SPFA()==true) add();
	printf("%d\n",ans);
	return 0;
}
做完这题,我知道了:可以根据流量平衡来进行网络流的建图,以后还有多多练习网络流
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BZOJ 2908 题目是一个数据下载任务。这个任务要求下载指定的数据文件,并统计文件中小于等于给定整数的数字个数。 为了完成这个任务,首先需要选择一个合适的网址来下载文件。我们可以使用一个网络爬虫库,如Python中的Requests库,来帮助我们完成文件下载的操作。 首先,我们需要使用Requests库中的get()方法来访问目标网址,并将目标文件下载到我们的本地计算机中。可以使用以下代码实现文件下载: ```python import requests url = '目标文件的网址' response = requests.get(url) with open('本地保存文件的路径', 'wb') as file: file.write(response.content) ``` 下载完成后,我们可以使用Python内置的open()函数打开已下载的文件,并按行读取文件内容。可以使用以下代码实现文件内容读取: ```python count = 0 with open('本地保存文件的路径', 'r') as file: for line in file: # 在这里实现对每一行数据的判断 # 如果小于等于给定整数,count 加 1 # 否则,不进行任何操作 ``` 在每一行的处理过程中,我们可以使用split()方法将一行数据分割成多个字符串,并使用int()函数将其转换为整数。然后,我们可以将该整数与给定整数进行比较,以判断是否小于等于给定整数。 最后,我们可以将统计结果打印出来,以满足题目的要求。 综上所述,以上是关于解决 BZOJ 2908 数据下载任务的简要步骤和代码实现。 希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值