牛奶调度(sched)

题目描述

农民约翰有N头奶牛(1<=N<=10,000),编号为1...N。每一头奶牛需要T(i)单位的时间来挤奶。不幸的是,由于FJ的仓库布局,一些奶牛要在别的牛之前挤奶。比如说,如果奶牛A必须在奶牛B前挤奶,FJ就需要在给奶牛B挤奶前结束给奶牛A的挤奶。

为了尽量完成挤奶任务,FJ聘请了一大批雇工协助任务——同一时刻足够去给任意数量的奶牛挤奶。然而,尽管奶牛可以同时挤奶,但仍需要满足以上的挤奶先后顺序。请帮助FJ计算挤奶过程中的最小总时间。

输入格式

第 1 行:两个空格分隔的整数:N(奶牛数量)和 M(挤奶约束数;1 <= M <= 50,000)。

第 2..1+N 行:第 i+1 行包含 T(i) 的值 (1 <= T(i) <= 100,000)。

第 2+N.行。1+N+M:每行包含两个空格分隔的整数 A 和 B,表示奶牛 A 必须完全挤奶,然后才能开始挤奶 B。这些约束永远不会形成循环,因此解决方案总是可能的。

输出格式

第 1 行:挤奶所需的最短时间。

输入输出样例

输入 #1

3 1 
10 
5 
6 
3 2

输出 #1

11

说明/提示

有3头奶牛。每头奶牛挤奶所需的时间分别为 10、5 和 6。3 号奶牛必须完全挤奶,然后才能开始挤奶 2 号奶牛。

1 号奶牛和 3 号奶牛最初可以同时挤奶。当奶牛 3 完成挤奶后,奶牛 2 就可以开始挤奶了。所有奶牛在经过 11 个单位的时间后完成挤奶。

实现代码(有坑,最好用链式前向星

#include<bits/stdc++.h>
using namespace std;
long long h[50005],to[50005],ne[50005],tot=0,wc[10005],js[10005],vis[10005];
void add(long long b,long long a)
{
	tot++;
	ne[tot]=h[a];
	to[tot]=b;
	h[a]=tot;
}
long long dfs(int a)
{
	if(vis[a]==1)
	{
		return js[a];
	}
	for(long long i=h[a];i;i=ne[i])
	{
		js[a]=max(js[a],dfs(to[i]));
		vis[to[i]]=1;
	}
	vis[a]=1;
	js[a]+=wc[a];
	return js[a];
}
int main()
{
	long long n,m,y,u,maxx=0,minn=0;
	scanf("%lld%lld",&n,&m);
	vis[0]=1;js[0]=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&wc[i]);vis[i]=1;
		js[i]=wc[i];
		maxx=max(maxx,wc[i]);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%lld%lld",&y,&u);vis[u]=0;js[u]=0;
		add(y,u);
	}
	for(int i=1;i<=n;i++)
	{
		if(vis[i]==1)
			continue;
		else
		{
			minn=max(minn,dfs(i));
			//cout<<i<<24;
		}
	}
	//for(int i=1;i<=n;i++)
	//cout<<js[i]<<" ";
	//cout<<'\n';
	printf("%lld", max(minn,maxx));
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值