Delay Constrained Maximum Capacity Path(HDU 1839)---二分枚举

题目链接

题目描述

Consider an undirected graph with N vertices, numbered from 1 to N, and M edges. The vertex numbered with 1 corresponds to a mine from where some precious minerals are extracted. The vertex numbered with N corresponds to a minerals processing factory. Each edge has an associated travel time (in time units) and capacity (in units of minerals). It has been decided that the minerals which are extracted from the mine will be delivered to the factory using a single path. This path should have the highest capacity possible, in order to be able to transport simultaneously as many units of minerals as possible. The capacity of a path is equal to the smallest capacity of any of its edges. However, the minerals are very sensitive and, once extracted from the mine, they will start decomposing after T time units, unless they reach the factory within this time interval. Therefore, the total travel time of the chosen path (the sum of the travel times of its edges) should be less or equal to T.

输入格式

The first line of input contains an integer number X, representing the number of test cases to follow. The first line of each test case contains 3 integer numbers, separated by blanks: N (2 <= N <= 10.000), M (1 <= M <= 50.000) and T (1 <= T <= 500.000). Each of the next M lines will contain four integer numbers each, separated by blanks: A, B, C and D, meaning that there is an edge between vertices A and B, having capacity C (1 <= C <= 2.000.000.000) and the travel time D (1 <= D <= 50.000). A and B are different integers between 1 and N. There will exist at most one edge between any two vertices.

输出格式

For each of the X test cases, in the order given in the input, print one line containing the highest capacity of a path from the mine to the factory, considering the travel time constraint. There will always exist at least one path between the mine and the factory obbeying the travel time constraint.

输入样例

2
2 1 10
1 2 13 10
4 4 20
1 2 1000 15
2 4 999 6
1 3 100 15
3 4 99 4

输出样例

13
99

分析

题目大意是有n个点和m条路线,每条路线都有限定货最大通过容量,求从1号点(矿山)到n号点(加工厂)在规定时间内到达的最小容量,这个最小容量是这条路径上各边容量的最小值。
本题主要是通过二分思想,二分枚举当前最小容量求最短路即可,具体看源码。
以下是分别用dijkstra、SPFA和SPFA(SLF优化)算法写成的源码。

源程序

Dijkstra算法

#include <bits/stdc++.h>
#define MAXN 10005
#define INF 0x3f3f3f3f
using namespace std;
struct Edge{	//链式前向星 
	int v,w,c,next;
	Edge(){};
	Edge(int _v,int _w,int _c,int _next){
		v=_v,w=_w,c=_c,next=_next; 
	};
	bool operator <(const Edge a)const{
		return w>a.w;
	};
}edge[MAXN*10];
int EdgeCount,head[MAXN];
int t,n,m,tim,dis[MAXN];
bool used[MAXN];
void addEdge(int u,int v,int w,int c)	//链式前向星建图 
{
	edge[++EdgeCount]=Edge(v,w,c,head[u]);
	head[u]=EdgeCount;
}
void dijkstra(int now)
{
	priority_queue<Edge> q;
	memset(dis,0x3f,sizeof(dis));
	memset(used,false,sizeof(used));
	dis[1]=0;
	q.push(Edge{1,0,0,0});
	while(!q.empty()){
		int u=q.top().v;q.pop();
		if(used[u])continue;
		used[u]=true;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].v,w=edge[i].w,c=edge[i].c;
			if(now>c)continue;	//当前容量超过边限定容量 
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				q.push(Edge{v,dis[v],0,0});
			} 
		}
	}
}
int main()
{
	scanf("%d",&t);
	while(t--){
		memset(head,0,sizeof(head));	//初始化 
		EdgeCount=0;
		scanf("%d%d%d",&n,&m,&tim);
		int imax=-INF,imin=INF;	//最大、最小容量 
		for(int i=1;i<=m;i++){	//建图 
			int u,v,w,c;
			scanf("%d%d%d%d",&u,&v,&c,&w);
			imax=max(imax,c),imin=min(imin,c); 
			addEdge(u,v,w,c);
			addEdge(v,u,w,c);
		}
		int l=imin,r=imax+1,ans;
		while(l<r){	//枚举最低容量 
			int mid=(l+r)>>1;
			dijkstra(mid);
			if(dis[n]==INF||dis[n]>tim)r=mid;	//无法到达或者无法按规定时间到达
			else{
				l=mid+1;
				ans=mid;
			}
		} 
		printf("%d\n",ans);
	}
} 

SPFA算法

#include <bits/stdc++.h>
#define MAXN 10005
#define INF 0x3f3f3f3f
using namespace std;
struct Edge{	//链式前向星 
	int v,w,c,next;
	Edge(){};
	Edge(int _v,int _w,int _c,int _next){
		v=_v,w=_w,c=_c,next=_next; 
	};
}edge[MAXN*10];
int EdgeCount,head[MAXN];
int t,n,m,tim,dis[MAXN];
bool ven[MAXN];
void addEdge(int u,int v,int w,int c)	//链式前向星建图 
{
	edge[++EdgeCount]=Edge(v,w,c,head[u]);
	head[u]=EdgeCount;
}
void SPFA(int now)
{
	queue<int> q;
	memset(dis,0x3f,sizeof(dis));
	memset(ven,false,sizeof(ven));
	dis[1]=0;
	ven[1]=1;
	q.push(1);
	while(!q.empty()){
		int u=q.front();q.pop();
		ven[u]=0;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].v,w=edge[i].w,c=edge[i].c;
			if(now>c)continue;	//当前容量超过边限定容量 
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				if(!ven[v]){
					q.push(v);
					ven[v]=1;
				}
			} 
		}
	}
}
int main()
{
	scanf("%d",&t);
	while(t--){
		memset(head,0,sizeof(head));	//初始化 
		EdgeCount=0;
		scanf("%d%d%d",&n,&m,&tim);
		int imax=-INF,imin=INF;	//最大、最小容量 
		for(int i=1;i<=m;i++){	//建图 
			int u,v,w,c;
			scanf("%d%d%d%d",&u,&v,&c,&w);
			imax=max(imax,c),imin=min(imin,c); 
			addEdge(u,v,w,c);
			addEdge(v,u,w,c);
		}
		int l=imin,r=imax+1,ans;
		while(l<r){	//枚举最低容量 
			int mid=(l+r)>>1;
			SPFA(mid);
			if(dis[n]==INF||dis[n]>tim)r=mid;	//无法到达或者无法按规定时间到达
			else{
				l=mid+1;
				ans=mid;
			}
		} 
		printf("%d\n",ans);
	}
} 

SPFA算法之SLF优化

#include <bits/stdc++.h>
#define MAXN 10005
#define INF 0x3f3f3f3f
using namespace std;
struct Edge{	//链式前向星 
	int v,w,c,next;
	Edge(){};
	Edge(int _v,int _w,int _c,int _next){
		v=_v,w=_w,c=_c,next=_next; 
	};
}edge[MAXN*10];
int EdgeCount,head[MAXN];
int t,n,m,tim,dis[MAXN];
bool ven[MAXN];
void addEdge(int u,int v,int w,int c)	//链式前向星建图 
{
	edge[++EdgeCount]=Edge(v,w,c,head[u]);
	head[u]=EdgeCount;
}
void SPFA(int now)
{
	deque<int> q;
	memset(dis,0x3f,sizeof(dis));
	memset(ven,false,sizeof(ven));
	dis[1]=0;
	ven[1]=1;
	q.push_back(1);
	int k;
	while(k=q.size()){
		int u=q.front();q.pop_front();
		ven[u]=0;
		for(int i=head[u];i;i=edge[i].next){
			int v=edge[i].v,w=edge[i].w,c=edge[i].c;
			if(now>c)continue;	//当前容量超过边限定容量 
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				if(!ven[v]){
					if(k>1&&dis[v]<dis[q.front()])q.push_front(v);
					else q.push_back(v);
					ven[v]=1;
				}
			} 
		}
	}
}
int main()
{
	scanf("%d",&t);
	while(t--){
		memset(head,0,sizeof(head));	//初始化 
		EdgeCount=0;
		scanf("%d%d%d",&n,&m,&tim);
		int imax=-INF,imin=INF;	//最大、最小容量 
		for(int i=1;i<=m;i++){	//建图 
			int u,v,w,c;
			scanf("%d%d%d%d",&u,&v,&c,&w);
			imax=max(imax,c),imin=min(imin,c); 
			addEdge(u,v,w,c);
			addEdge(v,u,w,c);
		}
		int l=imin,r=imax+1,ans;
		while(l<r){	//枚举最低容量 
			int mid=(l+r)>>1;
			SPFA(mid);
			if(dis[n]==INF||dis[n]>tim)r=mid;	//无法到达或者无法按规定时间到达
			else{
				l=mid+1;
				ans=mid;
			}
		} 
		printf("%d\n",ans);
	}
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的医院后台管理系统实现了病房管理、病例管理、处方管理、字典管理、公告信息管理、患者管理、药品管理、医生管理、预约医生管理、住院管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让医院后台管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值