P2176 [USACO11DEC] RoadBlock S / [USACO14FEB] Roadblock G/S

传送门

题目描述

每天早晨,FJ 从家中穿过农场走到牛棚。农场由 N N N 块农田组成,农田通过 M M M 条双向道路连接,每条路有一定长度。FJ 的房子在 1 1 1 号田,牛棚在 N N N 号田。没有两块田被多条道路连接,以适当的路径顺序总是能在农场任意一对田间行走。当 FJ 从一块田走到另一块时,总是以总路长最短的道路顺序来走。

FJ 的牛呢,总是不安好心,决定干扰他每天早晨的计划。它们在 M M M 条路的某一条上安放一叠稻草堆,使这条路的长度加倍。牛希望选择一条路干扰使得 FJ 从家到牛棚的路长增加最多。它们请你设计并告诉它们最大增量是多少。

输入格式

第 1 1 1 行:两个整数 N , M N, M N,M。

第 2 2 2 到 M + 1 M+1 M+1 行:第 i + 1 i+1 i+1 行包含三个整数 A i , B i , L i A_i, B_i, L_i Ai,Bi,Li, A i A_i Ai 和 B i B_i Bi 表示道路 i i i 连接的田的编号, L i L_i Li 表示路长。

输出格式

一个整数,表示通过使某条路加倍而得到的最大增量。

输入输出样例 #1

输入 #1

复制代码
5 7
2 1 5
1 3 1
3 2 8
3 5 7
3 4 3
2 4 7
4 5 2

输出 #1

复制代码
2

说明/提示

【样例说明】

若使 3 3 3 和 4 4 4 之间的道路长加倍,最短路将由 1 → 3 → 4 → 5 1 \rightarrow 3 \rightarrow 4 \rightarrow 5 1→3→4→5 变为 1 → 3 → 5 1 \rightarrow 3 \rightarrow 5 1→3→5。

【数据规模和约定】

对于 30 % 30\% 30% 的数据, N ≤ 70 N \le 70 N≤70, M ≤ 1   500 M \le 1\,500 M≤1500。

对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 100 1 \le N \le 100 1≤N≤100, 1 ≤ M ≤ 5   000 1 \le M \le 5\,000 1≤M≤5000, 1 ≤ L i ≤ 1   000   000 1 \le L_i \le 1\,000\,000 1≤Li≤1000000。

思路

首先跑一遍最短路,看原最短需要走多少。

接着,枚举在每条边放稻草堆,跑最短路,记录最大增量。

注意:不能直接在 FJ 原来走的最短路中最长的边放,因为他还可以走其他边。

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int g[100001],n,m,dis[100001],to[100001],cnt,head[100001],p,Next[100001],w[100001],maxn=INT_MIN;
bool vis[100001];
queue<int>q;
void add(int u,int v,int l)
{
	++cnt;
	to[cnt]=v;	
	Next[cnt]=head[u];
	head[u]=cnt;	
	w[cnt]=l;
}
void spfa()
{
	for(int i=1;i<=n;i++)
		dis[i]=INT_MAX;
	memset(vis,0,sizeof vis);
	dis[1]=0;	
	q.push(1);
	vis[1]=1;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		vis[u]=0;
		for(int i=head[u];i;i=Next[i])
		{
			int v=to[i];
			if(dis[v]>dis[u]+w[i])
			{
				dis[v]=dis[u]+w[i];
				if(!vis[v])
				{
					q.push(v);
					vis[v]=1;
				}			
			}	
		}
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}
	spfa();
	int disn=dis[n];
	for(int i=1;i<=m;i++)
	{
		w[i*2-1]*=2;
		w[i*2]*=2;
		spfa();
		maxn=max(maxn,dis[n]-disn);
		w[i*2-1]/=2;
		w[i*2]/=2;
	}
	cout<<maxn;
	return 0;
}
相关推荐
yi0117 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
灯澜忆梦9 小时前
【面向对象编程C++】| 基础语法
java·c++·算法
小蒋观天下9 小时前
专项方案:大场景港口AI安防、多干扰环境下的算法调优与落地实操
人工智能·深度学习·算法·安全·机器学习·计算机视觉·ai大模型
Evand J10 小时前
【电机滤波例程5】渐消因子自适应扩展卡尔曼滤波(EKF),MATLAB。PMSM负载突变下的状态估计。附下载链接
算法·matlab
H.莓飛10 小时前
【数据结构】二叉树_OJ题
linux·开发语言·数据结构·算法
好想像大佬一样能够ak所有11 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode
aqiu11111111 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
黄金龙PLUS11 小时前
如何基于置换算法来设计对称加密算法
算法·网络安全·密码学·哈希算法·同态加密
不会就选b11 小时前
算法日常・每日刷题--<动态规划>14
算法
赛博守夜人11 小时前
跨境业务与出海合规之九:海外买量投放与营销虚假流量(Ad Fraud):跨国机房群控与归因欺诈识别算法
算法·安全