P2176 [USACO14FEB]路障Roadblock

题目传送门

十分值得一做的最短路,题目意思十分明确,一条边权值加倍后最多比加倍前的最短路花费多多少。首先看到m<=5000,第一念头就是跑m遍最短路,但是会严重超时,实际上是由于有些边的权值改变,对最短路没有造成任何影响,才导致了我们程序的严重超时,所以我们采取第一次跑最短路记路径的方法。开三个辅助数组path[]、pre[]和edge[],path[]就是用来记最短路经过了哪些编号的边(邻接表存边),pre[i]表示走i号节点之前走的边,edge[i]表示到i号节点之前所经过的点,然后while循环逆推路径并记录,最后依次枚举最短路经过的边*2即可

算法步骤:

1)读入,邻接表存边,注意这里一定要用邻接表,不然后边不好记路径

2)先跑一遍SPFA,计算pre和edge数组,并求出“裸”的最短路

3)用while循环推导path数组

4)依次将path数组对应的每条边*2,并求出差值,打擂台取最大差值(计算完之后不要忘记除回来)

5)输出即可

参考程序如下:

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int ans,maxx,n,m,x,y,z,v[100001],w[100001],head[100001],nxt[100001],cnt,path[100001],dist[100001],pre[100001],now,num,edge[100001];
bool vis[100001];
void add(int a,int b,int c)
{
	v[++cnt]=b;
	w[cnt]=c;
	nxt[cnt]=head[a];
	head[a]=cnt;
}
void spfa(int s)
{
	memset(dist,20,sizeof(dist));
	queue<int>q;
	q.push(s);
	vis[s]=1;
	dist[s]=0;
	while(!q.empty())
	{
		int t=q.front();
		q.pop();
		vis[t]=0;
		for(int i=head[t];i;i=nxt[i])
		{
			int y=v[i];
			if(dist[y]>dist[t]+w[i])
			{
				dist[y]=dist[t]+w[i];
				pre[y]=i;edge[y]=t;
				if(!vis[y])
				{
					q.push(y);
					vis[y]=1;
				}
			}
		}
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}
	spfa(1);
	ans=dist[n];
	now=n;
	while(now!=1)//记录路径,本程序中最难理解的地方,请务必好好理解!!!
	{
		path[++num]=pre[now];
		now=edge[now];
	}
	for(int i=1;i<=num;i++)
	{
		w[path[i]]*=2;
		spfa(1);
		maxx=max(maxx,dist[n]);
		w[path[i]]/=2;
	}
	cout<<maxx-ans<<endl;
	return 0;
}

  

原文地址:https://www.cnblogs.com/szmssf/p/10989332.html

时间: 2024-10-10 10:12:26

P2176 [USACO14FEB]路障Roadblock的相关文章

[USACO14FEB]路障Roadblock

题目:洛谷P2176. 题目大意:有n个点m条无向边,一个人要从1走到n,他会走最短路.现在可以让一条边的长度翻倍,求翻倍后这个人要多走多少距离. 解题思路:首先可以知道,翻倍肯定是在最短路上的某条边翻,否则他走的路不会变.我们先跑一遍最短路,记录下走的边,再枚举哪条边翻倍,然后跑最短路,记录下答案即可. 此题好像卡SPFA,于是我用堆优化Dijkstra秒杀. 时间复杂度$O(nm\log n)$. C++ Code: #include<cstdio> #include<cstring

P2176路障与P1186玛丽卡与P1491集合位置全面胜利

P2176 [USACO14FEB]路障Roadblock P1186 玛丽卡 P1491 集合位置 怎么又做到三倍经验,五年计划都超额完成了 这几道题像极了. 想起来不难吧,要让边改变之后与原来的最短路差值最大,就把最短路上的边改了呗. 用一个队列来记录最短路上的边,然后枚举这个队列里的元素,依次改变,刷出最大值. 代码有点不好写,这次我加上注释了. 不要问我为什么变量名怎么这么长,最近沉迷代码补全. P2176的代码: #include<bits/stdc++.h> using names

(寒假集训)Roadblock(最短路)

Roadblock 时间限制: 1 Sec  内存限制: 64 MB提交: 9  解决: 5[提交][状态][讨论版] 题目描述 Every morning, FJ wakes up and walks across the farm from his house to the barn.  The farm is a collection of N fields (1 <= N <= 250) connected by M bidirectional pathways (1 <= M

络谷 P2865 [USACO06NOV]路障Roadblocks

P2865 [USACO06NOV]路障Roadblocks 题目描述 Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best friends. She does not want to get to her old home too quickly, because she likes the scenery along the way. She has decided t

洛谷P2237 [USACO14FEB]自动完成Auto-complete

洛谷P2237 [USACO14FEB]自动完成Auto-completeTrie树 1 #include <bits/stdc++.h> 2 #define For(i, j, k) for(int i=j; i<=k; i++) 3 #define Dow(i, j, k) for(int i=j; i>=k; i--) 4 #define LL long long 5 using namespace std; 6 inline int read() { 7 int x = 0

Roadblock

2428: Roadblock 时间限制: 1 Sec  内存限制: 64 MB提交: 17  解决: 6[提交] [状态] [讨论版] [命题人:admin] 题目描述 Every morning, FJ wakes up and walks across the farm from his house to the barn.  The farm is a collection of N fields (1 <= N <= 250) connected by M bidirectional

P3102 [USACO14FEB]秘密代码Secret Code

题目描述 Farmer John has secret message that he wants to hide from his cows; the message is a string of length at least 2 containing only the characters A..Z. To encrypt his message, FJ applies a sequence of "operations" to it, where an operation ap

java路障CyclicBarrier

当所有线程都执行到某行代码,才可已往下执行: package threadLock; import java.util.Random; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; pub

BZOJ 3445: [Usaco2014 Feb] Roadblock

Description 一个图, \(n\) 个点 \(m\) 条边,求将一条边距离翻倍后使 \(1-n\) 最短路径增加的最大增量. Sol Dijstra. 先跑一边最短路,然后枚举最短路,将路径翻倍然后跑Dijstra... 因为不在最短路径上的边没用贡献,然后最短路径最长为 \(n-1\) 复杂度 \(O(nmlogm\) Code /************************************************************** Problem: 3445