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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • cnn lstm pytorch_pytorch怎么用

    cnn lstm pytorch_pytorch怎么用LSTM模型结构1、LSTM模型结构2、LSTM网络3、LSTM的输入结构4、Pytorch中的LSTM4.1、pytorch中定义的LSTM模型4.2、喂给LSTM的数据格式4.3、LSTM的output格式5、LSTM和其他网络组合1、LSTM模型结构BP网络和CNN网络没有时间维,和传统的机器学习算法理解起来相差无几,CNN在处理彩色图像的3通道时,也可以理解为叠加多层,图形的三维矩阵当做空间的切片即可理解,写代码的时候照着图形一层层叠加即可。如下图是一个普通的BP网络和CNN网络。图中的隐

    2025年10月25日
    2
  • python精彩编程200例 pdf-Python程序设计 第3版pdf「建议收藏」

    Python程序设计第3版内容简介《Python程序设计第3版》是面向大学计算机科学专业的教材。本书以Python语言为工具,采用相当传统的方法,强调解决问题、设计和编程是计算机科学的核心技能。全书共13章,此外,还包含两个附录。第1章到第5章介绍计算机与程序、编写简单程序、数字计算、对象和图形、字符串处理等基础知识。第6章到第8章介绍函数、判断结构、循环结构和布尔值等话题。第9章到第1…

    2022年4月6日
    117
  • ubuntu16.04安装MATLAB R2017b步骤详解(附完整文件包)「建议收藏」

    ubuntu16.04安装MATLAB R2017b步骤详解(附完整文件包)「建议收藏」摘要:介绍在ubuntu16.04中从下载到安装成功的完整步骤。本文给出MATLABR2017b(Linux系统)的完整安装包百度云盘下载地址,逐步介绍一种简单易行的安装方法,在桌面创建快捷方式,最终完整运行。

    2022年4月30日
    45
  • 数组和链表的区别?「建议收藏」

    数组和链表的区别?「建议收藏」今天来说下两种最基本的数据结构——数组和链表,它们无处不在!下面我们来一一介绍下他们,首先了解下内存分配的!内存的工作原理假设你去看演出,需要将东西寄存。寄存处有一个柜子,柜子有很多抽屉。每个抽屉可放一样东西,你有两样东西要寄存,因此要了两个抽屉。现在你可以去看演出了!这大致就是计算机内存的工作原理。计算机就像是很多抽屉的集合体,每个抽屉都有地址。fe0ffeeb是一个内存单元的地址。需要将数据存储到内存时,你请求计算机提供存储空间,计算机给你一个存储地址。需要存储多项数据时,有两种基本方式

    2022年6月28日
    25
  • leetcode-189. 旋转数组

    leetcode-189. 旋转数组原题链接给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。进阶:尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?示例 1:输入: nums = [1,2,3,4,5,6,7], k = 3输出: [5,6,7,1,2,3,4]解释:向右旋转 1 步: [7,1,2,3,4,5,6]向右旋转 2 步: [6,7,1,2,3,4,5]向右旋转 3 步: [5,6,7,1,2,3,4]题解

    2022年8月8日
    6
  • Python删除字符串中指定字符

    Python删除字符串中指定字符删除特定位置字符使用.pop()方法,先将字符串转换为列表,再把列表转换成字符串。string1=’雪雪最大’#定义一个字符串list_str=list(string1)#将字符串转换为列表list_str.pop(1)#删去第一个字符string2=”.join(list_str)#再将列表转换成字符串print(string2)输出结果雪最大 删除指定字符方法一使用.replace()方法,删除(指定字符string=’雪雪最大’

    2022年6月10日
    43

发表回复

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

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