SPFA专题

1通往奥格瑞玛的道路

在艾泽拉斯,有n个城市。编号为1,2,3,...,n。

城市之间有m条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联盟的攻击,进而损失一定的血量。

每次经过一个城市,都会被收取一定的过路费(包括起点和终点)。路上并没有收费站。

假设1为暴风城,n为奥格瑞玛,而他的血量最多为b,出发时他的血量是满的。

歪嘴哦不希望花很多钱,他想知道,在可以到达奥格瑞玛的情况下,他所经过的所有城市中最多的一次收取的费用的最小值是多少。

输入输出格式

输入格式:

第一行3个正整数,n,m,b。分别表示有n个城市,m条公路,歪嘴哦的血量为b。

接下来有n行,每行1个正整数,fi。表示经过城市i,需要交费fi元。

再接下来有m行,每行3个正整数,ai,bi,ci(1<=ai,bi<=n)。表示城市ai和城市bi之间有一条公路,如果从城市ai到城市bi,或者从城市bi到城市ai,会损失ci的血量。

输出格式:

仅一个整数,表示歪嘴哦交费最多的一次的最小值。

如果他无法到达奥格瑞玛,输出AFK。

输入输出样例

输入样例#1: 复制

4 4 8

8

5

6

10

2 1 2

2 4 1

1 3 4

3 4 3

输出样例#1: 复制

10

说明

对于60%的数据,满足n≤200,m≤10000,b≤200

对于100%的数据,满足n≤10000,m≤50000,b≤1000000000

对于100%的数据,满足ci≤1000000000,fi≤1000000000,可能有两条边连接着相同的城市。

最大值最小?二分答案。但有血量怎么办?因为你想要走到奥格瑞玛,你不能死,那血扣的最少的时候你还死了说明不可能通过,也就是AFK。所以这可以刚开始用一个很大的答案试试,如果能通过,说明可行。然后二分答案,这里要注意一个大大大坑,你快排了cost,它所对应的节点也就改变了,就是说通过i节点的费用不是原来的了。所以你需要一个临时数组来代替cost快排,然后将这个数组作为二分答案的数组。他们两两不干扰。要注意数组后效性!

 var
x,y,z,n,m,b,mi,sum,l,r,mid,blood,ma,ans:int64;
a,w,cost,next,head,q,dis,c:array[..]of int64;
vis,bj:array[..]of boolean;
i,e:longint;
procedure sort(l,r:int64);
var
i,j,x,y:int64;
begin
i:=l;
j:=r;
x:=c[(l+r) div ];
repeat
while c[i]<x do
inc(i);
while x<c[j] do
dec(j);
if not(i>j) then
begin
y:=c[i];
c[i]:=c[j];
c[j]:=y;
inc(i);dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; procedure add(x,y,z:longint);
begin
inc(e);a[e]:=y;next[e]:=head[x];head[x]:=e;w[e]:=z;
end;
function check(mid:longint):boolean;
var h,t,u,v,i:longint;
begin
h:=;t:=;
fillchar(q,sizeof(q),);
fillchar(vis,sizeof(vis),false);
fillchar(bj,sizeof(bj),false);
q[]:=; vis[]:=true;
for i:= to n do dis[i]:=<<;
for i:= to n do if mid<cost[i] then bj[i]:=true;
dis[]:=;
while h<t do
begin
inc(h);
u:=q[h];
i:=head[u];
vis[u]:=false;
while i> do
begin
v:=a[i];
// if mid= then writeln(u,' ',v);
if (dis[u]+w[i]<dis[v])and(not bj[v]) then
begin
dis[v]:=dis[u]+w[i];
if (not vis[v])and(not bj[v]) then
begin
vis[v]:=true;
inc(t);
q[t]:=v;
end;
end;
i:=next[i];
end;
end;
if dis[n]>b then exit(false) else exit(true);
end;
begin
readln(n,m,b);
mi:=maxlongint;
for i:= to n do
begin
readln(cost[i]);
if ma<cost[i] then ma:=cost[i];
if mi>cost[i] then mi:=cost[i]; end;
c:=cost;
sort(,n);
for i:= to m do
begin
readln(x,y,z);
add(x,y,z);
add(y,x,z);
end;
l:=; r:=n;
if not check(maxlongint) then
begin writeln('AFK'); exit; end; while l<=r do
begin
mid:=(l+r)div ;
// blood:=b; if check(c[mid]) then
begin ans:=c[mid]; r:=mid-; end else l:=mid+;
end; writeln(ans);
end.

2 最优贸易noip2009

题解:

就因为我for 中m 打错成n就调了一个小时!?而且这已经不是第一次了!

------------------------------------------------------------------------------------

开始说正事。

本题很直观的就是想找到一个价格最低和一个价格最高点(满足由起点能到达, 且又可顺序到达终点),找最低价格的点可以这样来处理, 从源点开始找到所有点的最低价格(某个顶点的最低价格就是从源点到该所有可能路径上的价格最低的点), 最后枚举卖出的点,并且判断该点是否可以到达即可。 此外,由于数据规模较大,一般的邻接矩阵难以承受, 因此采用动态数据结构邻接表。但是本题有环,处理时还有几个细节问题: 1.由于是最后要判定所有的顶点是否可以到达终点, 因此不妨将所有的边反向,由终点出发判断终点可以到达那些顶点就可以了, 并做上标记。这样也就要求在读入边的时候必须反向再储存一次。 2.用SPFA求某个顶点的最低价格时,对SPFA进行了改进。 由SPFA的原理可以知道,该算法可以处理环的问题, 但是要求最短路径的长度是可以收敛的,也就是说不能在图中存在负权。 该题目满足此要求。SPFA是用来求最短路径的算法,在此对其改进, 来求路径上最小价格的点。

 var
e,ie,x,y,z,u,h,t,n,m,i,j,k,ans,v:longint;
head,b,next,ihead,inext,a,ib,maxp,minp,q:array[..]of longint;
vis:array[..]of boolean;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
function min(x,y:longint):longint;
begin
if x>y then exit(y) else exit(x);
end;
procedure add(x,y:longint);
begin
inc(e);b[e]:=y;next[e]:=head[x];head[x]:=e;
end;
procedure iadd(x,y:longint);//反向建边
begin
inc(ie);ib[ie]:=y;inext[ie]:=ihead[x];ihead[x]:=ie;
end;
procedure spfa1;
var i,j,h,t,u,v:longint;
begin
for i:= to n do minp[i]:=maxlongint;
h:=;t:=; q[]:=;vis[]:=true;
minp[]:=a[];
while h<t do
begin
inc(h);
u:=q[h];
vis[u]:=false;
i:=head[u];
while i> do
begin
v:=b[i];
if minp[v]>minp[u] then
begin
minp[v]:=minp[u];
minp[v]:=min(minp[v],a[v]);
if not vis[v] then
begin
vis[v]:=true;
inc(t);
q[t]:=v;
end;
end;
i:=next[i];
end;
end; end;
procedure spfa2;
var i,j,h,t,u,v:longint;
begin
fillchar(q,sizeof(q),);
fillchar(vis,sizeof(vis),false);
h:=;t:=;
q[]:=n; vis[n]:=true;
maxp[n]:=a[n];
while h<t do
begin
inc(h);
u:=q[h];
i:=ihead[u];
vis[u]:=false;//打在前面有负环也能运行
while i> do
begin
v:=ib[i];
if maxp[v]<maxp[u] then // you wrong here
begin
maxp[v]:=maxp[u];
maxp[v]:=max(maxp[v],a[v]);
if not vis[v] then
begin
vis[v]:=true;
inc(t);
q[t]:=v;
end;
end;
i:=inext[i]; end;
end; end;
begin
readln(n,m);
for i:= to n do
read(a[i]);
for i:= to m do//m 不要再打成n了!
begin
readln(x,y,z);
add(x,y);
iadd(y,x);
if z= then
begin
add(y,x);
iadd(x,y);
end;
end;
spfa1;
spfa2;
for i:= to n do
if maxp[i]-minp[i]>ans then ans:=maxp[i]-minp[i];
writeln(ans);
end.

spfa专题的更多相关文章

  1. [bzoj2118]墨墨的等式【dijk+堆】

    10/30的update:如果是冲着dijk的板子来的,建议看多校联考contest中第二场day2的T2,那边的写法比较优秀... --------------------------------- ...

  2. 算法专题 | 10行代码实现的最短路算法——Bellman-ford与SPFA

    今天是算法数据结构专题的第33篇文章,我们一起来聊聊最短路问题. 最短路问题也属于图论算法之一,解决的是在一张有向图当中点与点之间的最短距离问题.最短路算法有很多,比较常用的有bellman-ford ...

  3. 【算法系列学习】SPFA邻接表最短路 [kuangbin带你飞]专题四 最短路练习 F - Wormholes

    https://vjudge.net/contest/66569#problem/F 题意:判断图中是否存在负权回路 首先,介绍图的邻接表存储方式 数据结构:图的存储结构之邻接表 邻接表建图,类似于头 ...

  4. 并不对劲的图论专题(三):SPFA算法的优化

    1.bzoj1489-> 这是个新套路. 我们希望找到最小的x,那么可以二分x,然后判断是否存在圈的边权的平均值小于等于x. 设圈的边权依次为w1,w2,w3,…,wk,平均值为p, 则有p= ...

  5. CSU1333最短路问题SPFA

    fastvj.rainng.com/contest/236779#problem/I Description: n个点m条路每条路 l,r,t:表示这条路开l秒,关r秒,通过要t秒,问你车辆从s到t最 ...

  6. LightOJ 1074 - Extended Traffic (SPFA)

    http://lightoj.com/volume_showproblem.php?problem=1074 1074 - Extended Traffic   PDF (English) Stati ...

  7. [专题总结]初探插头dp

    彻彻底底写到自闭的一个专题. 就是大型分类讨论,压行+宏定义很有优势. 常用滚动数组+哈希表+位运算.当然还有轮廓线. Formula 1: 经过所有格子的哈密顿回路数. 每个非障碍点必须有且仅有2个 ...

  8. 学习笔记--APIO 2018 二分专题 By wuvin

    前言: 在APIO 2018 Day2下午听wuvin讲二分,听了一上午的神仙,现在终于有可以听懂了. 专题: 平均边权最大 题目链接:https://www.questoj.cn/problem/3 ...

  9. NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先

    系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 最短路 Floyd 基本思路:枚举所有点与点的中点,如果从中点走最短,更新两点间 ...

随机推荐

  1. March 29 2017 Week 13 Wednesday

    It's during our darkest moments that we must focus to see the light. 在最黑暗的时刻,最该努力看到光. I always thoug ...

  2. python入门14 字典dict

    字典dict是无序的key:value格式的数据序列 #coding:utf-8 #/usr/bin/python """ 2018-11-11 dinghanhua 字 ...

  3. 关于bootstrap-table服务端分页问题

    昨天项目中涉及到了前端表格分页问题.数据一共有1万多条,所以选择了后端分页. 之前用的都是前端分页,第一次使用后端分页.网上也找到了一些例子,最后做出来了. 这里用的是bootstrap-table插 ...

  4. Android(java)学习笔记38:Android 短信发送

    1.第一种可以调用系统内部的短信程序. 之前我曾经出现过一个bug就是报错: android.content.ActivityNotFoundException: No Activity found ...

  5. Ural State University Internal Contest October'2000 Junior Session

    POJ 上的一套水题,哈哈~~~,最后一题很恶心,不想写了~~~ Rope Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7 ...

  6. ACM-ICPC (10/15) Codeforces Round #440 (Div. 2, based on Technocup 2018 Elimination Round 2)

    A. Search for Pretty Integers You are given two lists of non-zero digits. Let's call an integer pret ...

  7. HDU 2082 普通型母函数

    分析: 组成单词好说,价值如何体现? 改变指数就行,例如: 这样,组成的单词,指数就是权值,多项式相乘,指数小于50的就OK: #include <bits/stdc++.h> using ...

  8. 【luogu P2324 [SCOI2005]骑士精神】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2324 不懂怎么剪枝,所以说,,我需要氧气.. 第一道A* // luogu-judger-enable-o2 ...

  9. google为什么将爬虫从python移植到C++

    这是好几年前Quora上的一个问题,有点过时,但看了之后感觉不错,就总结了一下 原文链接:http://www.quora.com/Why-did-Google-move-from-Python-to ...

  10. Ajax,Json数据格式

    同步和异步 同步现象:客户端发送请求到服务器端,当服务器返回响应之前,客户端都处于等待     卡死状态 异步现象:客户端发送请求到服务器端,无论服务器是否返回响应,客户端都可以随     意做其他事 ...