ZOJ 3794 Greedy Driver spfa

ZOJ 3794 Greedy Driver spfa

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

题意:

给定n个点,m条有向边,邮箱容量。

起点在1,终点在n,開始邮箱满油。

以下m行表示起点终点和这条边的耗油量(就是长度)

再以下给出一个数字m表示有P个加油站,能够免费加满油。

以下一行P个数字表示加油站的点标。

再以下一个整数Q

以下Q行 u v 表示在u点有销售站,能够卖掉邮箱里的随意数量的油,每以单位v元。

问跑到终点能获得最多多少元。

先求个每一个点的最大剩余油量 f[i],

再把边反向,求每一个点距离终点的最短路 dis[i]。

然后枚举一下每一个销售点就可以,( f[i] – dis[i] ) * v。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define N 10050
#define M 200010
#define inf 1000000
#define ll long long
struct Edge{
	int from, to, dis, nex;
}edge[M], e[M];
int head[N],edgenum;
void add(int u,int v,int d){
	Edge E={u,v,d,head[u]};
	edge[edgenum] = E;
	head[u] = edgenum++;
}
int H[N], edg;
void add2(int u,int v,int d){
	Edge E={u,v,d,H[u]};
	e[edg] = E;
	H[u] = edg++;
}
int n, m, k;
int F[N], T[N];//F是车站 T是贩卖点
int f[N];//起点到这里最多能剩多少油
bool inq[N];
void spfa(){
	queue<int>q;
	memset(f,-1,sizeof f);
	memset(inq, 0, sizeof inq);
	f[1] = k; q.push(1);
	while(!q.empty()){
		int u = q.front(); q.pop(); inq[u] = 0;
		for(int i = head[u]; ~i; i = edge[i].nex){
			int v = edge[i].to;
			if(f[v]< f[u] - edge[i].dis){
				if(F[v])f[v]=k;
				else
				f[v] = f[u] - edge[i].dis;
				if(!inq[v])inq[v] = 1, q.push(v);
			}
		}
	}
}
int dis[N];//把边反一下跑出距离终点的最短路,也就是从这个点到终点最少要多少油
void bfs(){
	for(int i = 1; i <= n; i++)dis[i] = inf;
	memset(inq, 0, sizeof inq);
	dis[n] = 0;
	queue<int>q; q.push(n);
	while(!q.empty()){
		int u = q.front(); q.pop(); inq[u] = 0;
		for(int i = H[u]; ~i ; i = e[i].nex){
			int v = e[i].to;
			
			if(dis[v]>dis[u]+e[i].dis){
				if(F[v])dis[v] = 0; //由于v是加油站,所以到这点剩下0的油量也没事,自然会补满的
				else
				dis[v] = dis[u]+e[i].dis;
				if(!inq[v])inq[v] = 1, q.push(v);
			}
		}
	}
}
void init(){memset(head, -1, sizeof head);edgenum = 0;memset(H, -1, sizeof H);edg = 0;}
int main(){
	int i,u,v,d;
	while(~scanf("%d %d %d",&n,&m,&k)){
		init();
		memset(F, 0, sizeof F);
		memset(T, 0, sizeof T);
		while(m--){
			scanf("%d %d %d",&u,&v,&d);
			add(u,v,d);
			add2(v,u,d);
		}
		scanf("%d",&m);		while(m--){scanf("%d",&u);F[u]=1;}
		scanf("%d",&m);		while(m--){scanf("%d %d",&u,&v);T[u]=v;}
		spfa();
		if(f[n]==-1){puts("-1");continue;}
		bfs();
		int ans = 0;
		for(int i = 1; i <= n; i++)if(T[i] && f[i]!=-1&&dis[i]<inf)
			ans = max(ans, (f[i] - dis[i])*T[i]);
		cout<<ans<<endl;
	}
	return 0;
}
/*
2 1 1
1 2 2
1
1
0


*/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118579.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • so文件格式详解_文件xls文件怎么打开

    so文件格式详解_文件xls文件怎么打开可执行链接格式(ExecutableandLinkingFormat)最初是由UNIX系统实验室(UNIXSystemLaboratories,USL)开发并发布,作为应用程序二进制接口(ApplicationBinaryInterface,ABI)的一部分,它是一种常用的目标文件格式,主要包含以下三种类型1、可重定位文件:可与其它目标文件一起创建可执行文件和共

    2022年9月15日
  • java calendar 设置小时_Java Calendar类的时间操作[通俗易懂]

    java calendar 设置小时_Java Calendar类的时间操作[通俗易懂]JavaCalendar类时间操作,这也许是创建日历和管理最简单的一个方案,示范代码很简单,演示了获取时间,日期时间的累加和累减,以及比较。注意事项:Calendar的month从0开始,也就是全年12个月由0~11进行表示。而Calendar.DAY_OF_WEEK定义和值如下:Calendar.SUNDAY=1Calendar.MONDAY=2Calend…

    2022年4月30日
  • iOS之深入解析Xcode 13正式版发布的40个新特性

    iOS之深入解析Xcode 13正式版发布的40个新特性一、前言Xcode13包括适用于iOS15、iPadOS15、tvOS15、watchOS8和macOSBigSur11.3的SDK。Xcode13ReleaseCandidate支持iOS9及更高版本、tvOS9及更高版本以及watchOS2及更高版本的设备上调试。Xcode13需要运行macOS11.3或更高版本的Mac。二、通用Xcode13包括对Swift并发编程的原生支持、对XcodeCloud持续集成和

    2022年4月29日
  • ScheduledExecutorService 接口[通俗易懂]

    ScheduledExecutorService 接口[通俗易懂]newScheduledThreadPool()或者newSingleThreadScheduled-Executor()方法:延迟执行、周期性执行的执行器如果想在某一段时间之后执行线程操作,或者周期性地重复执行线程操作,则可以使用工厂类Executors的newScheduledThreadPool()方法或者newSingleThreadSche…

    2022年5月5日
  • Android 基于TCP的 Socket 编程实现(结合 okio)

    Android 基于TCP的 Socket 编程实现(结合 okio)两个进程如果要进行通讯最基本的一个前提就是能够唯一的标识一个进程,在本地进程通讯中我们可以使用PID来唯一标识一个进程,但PID只在本地是唯一的,网络中两个进程PID冲突几率很大,这时我们就需要通过其他手段来唯一标识网络中的进程了,我们知道IP层的ip地址可以唯一标示主机,而TCP层协议和端口号结合就可以唯一标示主机的一个进程了。

    2022年6月7日
  • JAVA float转int 如何取整_int型变量n转化成float

    JAVA float转int 如何取整_int型变量n转化成float网上巴巴的说了那么多,倒是给个结论啊.搜索半天,浪费一堆时间,不知道到底哪个说的对哪个说的错.直接自己写着看吧. floata1=2.42f; floata2=2.13f; floata3=2.89f; floata4=2.99f; floata5=2.35f; floata6=35.67f; floata7=9.8f; …

    2022年10月26日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号