计蒜客·安排工作

【拓扑排序】

初见安~本题选自计蒜客。

Description

蒜头君在公司有 n 件工作要做,现在已知每一件工作需要的时间 p 和完成这项工作的最晚期限 d。工作之间有 m 个限制关系,每一个限制关系是限制一项工作 x 一定要在另一项工作 y 之前完成。

蒜头君工作压力太大,不能按期限完成工作,他想要给自己安排一下工作的顺序,使得每项工作拖最晚期限的时间的最大值最小。

即如果设编号为 i 的工作的完成时间为 ci 的话,要求安排一种工作顺序,使得 max(ci−di,0) 最小,求出这个最小值。

Input

第一行两个整数 n,m(1≤n≤104,1≤m≤105),表示同学数和要求数;

接下来 n 行,每行两个整数 p,d,之间用一个空格隔开,表示每项工作需要的时间 p(1≤p≤104) 和完成这项工作的最晚期限 d(0≤d≤106);

再接下来 m 行,每行两个整数 x,y ,表示编号为 x 的任务一定要在编号为 y 的任务之前完成,任务编号从 1 开始;

输入保证一定能有一种安排方式可以满足所有限制关系。

Output

输出一行,包括 1 个整数,表示每项工作拖最晚期限的时间的最大值的最小值。若没有一个工作被拖延,则输出0。

Sample Input

2 1
1 0
2 1
1 2

Sample Output

2

题解

本题由于要最晚期限的时间的最大值 最小(这句话我都卡了好久才看懂 ),且时间是会累加的,所以我们考虑的大致方向应为最小,然后找出哪项工作拖延的时间最长。
所以我们可以用到一个优先队列——priority queue。拓扑排序时,由于存图方式为链表(方便 ),所以存入优先队列的为结构体,涉及到一个重定向操作——operator,让队列从小到大优先排序则重定向<。
下面是代码——(附解释)

#include<bits/stdc++.h>
using namespace std;
const int N=100000;
int m,n;
int p[N],d[N],du[N];
int head[N],k=0;//头结点
int ans=-32767,tme=0;
struct node
{
	int num,p,d,t;//序号,耗时,限时,时间
	node(int nn,int pp,int dd,int tt)
	{
		num=nn;p=pp;d=dd;t=tt;
	}
	bool operator < (const node &nd) const// 重定向
	{
		if(t!=nd.t) return t > nd.t;
		else return max(p - d , p + nd.p - nd.d) > max(nd.p - nd.d , p + nd.p -d);
	}
};

struct edge
{
	int v,next;
	edge(){}
	edge(int vv,int ee)
	{
		v=vv;next=ee;
	}
}e[N];

void add(int u,int v)//存边
{
	e[k]=edge(v,head[u]);
	head[u]=k++;
	du[v]++;
}
void topo()
{
	priority_queue<node> q;//优先队列
	for(int i=1;i<=n;i++)
	{
		if(du[i]==0) q.push(node(i,p[i],d[i],1));
	}
	
	while(!q.empty())
	{
		node now=q.top();
		q.pop();
		tme+=now.p;//累加时间
		ans=max(ans,tme-now.d);//此方法为默认时间尽量短,所以ans求在此情况下的最大值即可
		for(int i=head[now.num];~i;i=e[i].next)
		{
			int v=e[i].v;
			du[v]--;
			if(du[v]==0) q.push(node(v,p[v],d[v],now.t+1));
		}
	}
}

int main()
{
	memset(head,-1,sizeof head);//存结点时,以-1结尾表示到头了。因为数组没有下标为-1的
	memset(du,0,sizeof du);
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>p[i]>>d[i];
	for(int i=1;i<=m;i++)
	{
		int a,b;
		cin>>a>>b;
		add(a,b);
	}
	topo();
	if(ans>=0) cout<<ans<<endl;
	else cout<<"0"<<endl;
	return 0;
}

迎评:)
——End——

猜你喜欢

转载自blog.csdn.net/qq_43326267/article/details/82933060