列表

详情


NC22811. Happy new semester

描述

新学期开始了,大活一楼又堆起了山一样高的教材,而这学期学校特地推出了送书服务,不需要自己去买,直接在易班APP上下单就会有人把教材送到寝室楼一楼。

这个服务让学生们雀跃不已,但是可让负责管理教材运输的老师发了愁,每个运输工的力气都是有限的,怎么样才能最大效率的运送教材呢,于是他盯上了正在比赛的小西小理,打算让他们比赛设计出最好的运输方案,于是你作为小西的专属小抄,这个任务自然又落到了你的头上。

现在有力气值为c的一批运输工,整个学校中有n-1个宿舍楼需要运书。大活的编号为0,宿舍楼的编号为1~n-1。一共有m条可供选择的路线,其中第i条路线从Ui到Vi,最多运输的教材为Wi,消耗的力气值为Ci。每个宿舍楼只能从一个地方接收教材,但可以往多个宿舍楼运送教材。为了最大化每个运输工的作用,你的任务是设计出一个运送方案使路线中最小的教材运输量最大。

输入描述

输入第一行为数据组数T(T<=50)。每组数据第一行为3个整数n,m,c(1<=n<=60,1<=m<=10000,1<=c<=1e9)。

以下m行每行有4个整数Ui,Vi,Wi,Ci(0<=Ui,Vi<n,1<=Wi,Ci<=1e6,Ui!=Vi)描述一条运输线路。

输出描述

对每组数据,输出最小运煤量的最大值。若无法搭建网络,则输出“NO”(不含引号),输出占一行。

示例1

输入:

2
2 2 1
0 1 2 1
0 1 1 1
3 4 300
0 1 128 100
1 2 256 200
2 1 256 200
0 2 512 300

输出:

2
128

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 22ms, 内存消耗: 464K, 提交时间: 2020-03-17 14:49:13

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
const int INF=100000000;
const int MAXN=1010;
const int MAXM=1010000;
#define ll int
struct Edge
{
	int u,v;
	ll cost;
}edge[MAXM];
int pre[MAXN],id[MAXN],visit[MAXN],edgenum;
void addedge(int u,int v,int cost)
{
	Edge E={u,v,cost};
	edge[edgenum++]=E;
}
ll in[MAXN];
ll zhuliu(int root,int n,int m,Edge edge[],int c)
{
	int u,v;
	ll res=0;
	while(1)
	{
		for(int i=0;i<n;i++)
		in[i]=INF;
		for(int i=0;i<m;i++)
		if(edge[i].u!=edge[i].v&&edge[i].cost<in[edge[i].v])
		{
			pre[edge[i].v]=edge[i].u;
			in[edge[i].v]=edge[i].cost;
		}
		for(int i=0;i<n;i++)
		if(i!=root&&in[i]==INF)
		return -1;
		int tn=0;
		memset(id,-1,sizeof(id));
		memset(visit,-1,sizeof(visit));
		in[root]=0;
		for(int i=0;i<n;i++)
		{
			res+=in[i];
			if(res>c) return -1;
			v=i;
			while(visit[v]!=i&&id[v]==-1&&v!=root)
			{
				visit[v]=i;
				v=pre[v];
			}
			if(v!=root&&id[v]==-1)
			{
				for(int u=pre[v];u!=v;u=pre[u])
				id[u]=tn;
				id[v]=tn++;
			}
		}
		if(tn==0) break;
		for(int i=0;i<n;i++)
		if(id[i]==-1)
		id[i]=tn++;
		for(int i=0;i<m;)
		{
			v=edge[i].v;
			edge[i].u=id[edge[i].u];
			edge[i].v=id[edge[i].v];
			if(edge[i].u!=edge[i].v)
			edge[i++].cost-=in[v];
			else
			swap(edge[i],edge[--m]);
		}
		n=tn;
		root=id[root];
	 } 
	 return res;
}
void init()
{
	edgenum=0;
}
struct node
{
	ll u,v,bit,cost;
}E[MAXM];
int n,m,c;
bool ok(int x)
{
	init();
	for(int i=0;i<m;i++)
	if(E[i].bit>=x)
	addedge(E[i].u,E[i].v,E[i].cost);
	int ans=zhuliu(0,n,edgenum,edge,c);
	return ans<=c&&ans!=-1;
}
int main()
{
	int T,i;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d %d %d",&n,&m,&c);
		for(i=0;i<m;i++)
		scanf("%d %d %d %d",&E[i].u,&E[i].v,&E[i].bit,&E[i].cost);
		int l=1,r=1000000;
		int ans=0;
		while(l<=r)
		{
			int mid=(l+r)>>1;
			if(ok(mid))
			l=mid+1,ans=max(ans,mid);
			else r=mid-1;
		}
		ans==0?puts("NO"):printf("%d\n",ans);
	}
	return 0;
}

上一题