sgu 240 Runaway (spfa)
题意:N点M边的无向图,边上有线性不下降的温度,给固定入口S,有E个出口。逃出去,使最大承受温度最小。输出该温度,若该温度超过H,输出-1。
羞涩的题意
显然N*H的复杂度dp[n][h]表示到达n最大温度为h的最小时间(由于温度不下降,这样不会更差,故可以这么搞)
一开始读错题了,以为是温度累加什么鬼...
然后分别写了2种方法,二分和不二分的
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <queue>
using namespace std; #define ll long long
#define MP make_pair #define inf 0x3f3f3f3f
#define eps 1e-8 #define maxn 110
struct edge{
int v,nxt;
int w,r,p;
}e[maxn*maxn*];
int head[maxn], sz;
void init(){sz=;memset(head,-,sizeof(head));}
void addedge(int u,int v,int w,int ri,int pi){
e[sz].v=v,e[sz].nxt=head[u];
e[sz].w=w,e[sz].r=ri,e[sz].p=pi;
head[u]=sz++;
}
int dp[maxn][];
bool ed[maxn];
bool ins[maxn][];
int pre[maxn][][];
int getout;
void dfs(int u,int hp,int S,int cnt){
if(u==S){printf("%d %d",cnt+,u);return ;}
dfs(pre[u][hp][],pre[u][hp][],S,cnt+);
printf(" %d",u);
}
bool check(int mahp, int S){
memset(dp,0x3f,sizeof(dp));
dp[S][] = ;
memset(ins,false,sizeof(ins));
ins[S][] = true;
queue<pair<int,int> >que;
que.push(MP(S,));
if(ed[S]){getout = S;return true;}
while(!que.empty()){
int u = que.front().first;
int hp = que.front().second;
int t = dp[u][hp];
que.pop();
ins[u][hp] = false;
for(int i=head[u];i!=-;i=e[i].nxt){
int v = e[i].v;
int w = e[i].w;
int r = e[i].r;
int p = e[i].p;
ll tmp = r+p*(t+w);
if(tmp>mahp) continue;
int hp2 = max(hp,int(tmp));
if(dp[v][hp2]>dp[u][hp]+w){
pre[v][hp2][] = u;
pre[v][hp2][] = hp;
if(ed[v]){getout = v;return true;}
dp[v][hp2] = dp[u][hp]+w;
if(ins[v][hp2]==false){
ins[v][hp2] = true;
que.push(MP(v,hp2));
}
}
}
}
return false;
}
int main(){
int n,m,H,S,E;
while(~scanf("%d%d%d%d%d",&n,&m,&H,&S,&E)){
memset(ed,false,sizeof(ed));
init();
for(int i=;i<m;++i){
int u,v,w,r,p;
scanf("%d%d%d%d%d",&u,&v,&w,&r,&p);
addedge(u,v,w,r,p);
addedge(v,u,w,r,p);
}
for(int i=;i<E;++i){
int tmp;
scanf("%d",&tmp);
ed[tmp] = true;
}
int l=,r=H+;
while(l<r){
int mid = (l+r)/;
if(check(mid,S)) r = mid;
else l = mid+;
}
if(r<=H){
puts("YES");
printf("%d\n",r);
check(r,S);
dfs(getout,r,S,);
puts("");
}else puts("NO");
}
return ;
}
二分代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <queue>
using namespace std; #define ll long long
#define MP make_pair #define inf 0x3f3f3f3f
#define eps 1e-8 #define maxn 110
struct edge{
int v,nxt;
int w,r,p;
}e[maxn*maxn*];
int head[maxn], sz;
void init(){sz=;memset(head,-,sizeof(head));}
void addedge(int u,int v,int w,int ri,int pi){
e[sz].v=v,e[sz].nxt=head[u];
e[sz].w=w,e[sz].r=ri,e[sz].p=pi;
head[u]=sz++;
}
int dp[maxn][];
bool ed[maxn];
bool ins[maxn][];
int pre[maxn][][];
void dfs(int u,int hp,int S,int cnt){
if(u==S){printf("%d %d",cnt+,u);return ;}
dfs(pre[u][hp][],pre[u][hp][],S,cnt+);
printf(" %d",u);
}
pair<int,int> spfa(int mahp, int S){
int getout=-,ans = mahp+;
memset(dp,0x3f,sizeof(dp));
dp[S][] = ;
memset(ins,false,sizeof(ins));
ins[S][] = true;
queue<pair<int,int> >que;
que.push(MP(S,));
if(ed[S]) return MP(S,);
while(!que.empty()){
int u = que.front().first;
int hp = que.front().second;
int t = dp[u][hp];
que.pop();
ins[u][hp] = false;
if(hp>=ans) continue;
for(int i=head[u];i!=-;i=e[i].nxt){
int v = e[i].v;
int w = e[i].w;
int r = e[i].r;
int p = e[i].p;
ll tmp = r+p*(t+w);
if(tmp>mahp) continue;
int hp2 = max(hp,int(tmp));
if(hp2>=ans) continue;
if(dp[v][hp2]>dp[u][hp]+w){
pre[v][hp2][] = u;
pre[v][hp2][] = hp;
if(ed[v]){
getout = v;
ans = hp2;
}
dp[v][hp2] = dp[u][hp]+w;
if(ins[v][hp2]==false){
ins[v][hp2] = true;
que.push(MP(v,hp2));
}
}
}
}
return MP(getout,ans);
}
int main(){
int n,m,H,S,E;
while(~scanf("%d%d%d%d%d",&n,&m,&H,&S,&E)){
memset(ed,false,sizeof(ed));
init();
for(int i=;i<m;++i){
int u,v,w,r,p;
scanf("%d%d%d%d%d",&u,&v,&w,&r,&p);
addedge(u,v,w,r,p);
addedge(v,u,w,r,p);
}
for(int i=;i<E;++i){
int tmp;
scanf("%d",&tmp);
ed[tmp] = true;
}
pair<int,int> cur = spfa(H,S);
int getout = cur.first;
int ans = cur.second;
if(getout!=-){
puts("YES");
printf("%d\n",ans);
dfs(getout,ans,S,);
puts("");
}else puts("NO");
}
return ;
}
非二分代码
sgu 240 Runaway (spfa)的更多相关文章
- 模板C++ 03图论算法 1最短路之单源最短路(SPFA)
3.1最短路之单源最短路(SPFA) 松弛:常听人说松弛,一直不懂,后来明白其实就是更新某点到源点最短距离. 邻接表:表示与一个点联通的所有路. 如果从一个点沿着某条路径出发,又回到了自己,而且所经过 ...
- 最短路(SPFA)
SPFA是Bellman-Ford算法的一种队列实现,减少了不必要的冗余计算. 主要思想是: 初始时将起点加入队列.每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将 ...
- Bellman-Ford算法及其队列优化(SPFA)
一.算法概述 Bellman-Ford算法解决的是一般情况下的单源最短路径问题.所谓单源最短路径问题:给定一个图G=(V,E),我们希望找到从给定源结点s属于V到每个结点v属于V的最短路径.单源最短路 ...
- codevs 1021 玛丽卡(spfa)
题目描述 Description 麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复. 因为她和他们不住在同一个城市,因此她开始准备她的长途旅行. 在这个国家中每两个城市之间最多只有一条路相通,并且我们 ...
- 【POJ】1062 昂贵的聘礼(spfa)
http://poj.org/problem?id=1062 此题一开始果断想到暴力.. 但是n<=100果断不行. 一看题解,噗!最短路... 构图很巧妙. 每一个物品对应的所需物品相当于一个 ...
- POJ1860Currency Exchange(SPFA)
http://poj.org/problem?id=1860 题意: 题目中主要是说存在货币兑换点,然后现在手里有一种货币,要各种换来换去,最后再换回去的时候看能不能使原本的钱数增多,每一种货币都有 ...
- 【NOIP 2013 DAY2 T3】 华容道(spfa)
题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间. 小 ...
- HDU ACM 1690 Bus System (SPFA)
Bus System Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- Haunted Graveyard ZOJ - 3391(SPFA)
从点(n,1)到点(1,m)的最短路径,可以转换地图成从(1,1)到(n,m)的最短路,因为有负权回路,所以要用spfa来判负环, 注意一下如果负环把终点包围在内的话, 如果用负环的话会输出无穷,但是 ...
随机推荐
- 标准库String类
下面的程序并没有把String类的所有成员方法实现,只参考教程写了大部分重要的成员函数. [cpp] view plain copy #include<iostream> #include ...
- C#-WebForm-★★★ 分页展示 ★★★
什么是"分页展示"? 分页展示就是将庞大的数据分成若干页,每页展示若干条数据,向用户展示数据 流程:客户端浏览器向服务器发送查询请求 → 服务器从数据库查询数据 → 服务器转换成代 ...
- gg
纪念那段为了梦想的青春岁月,CS. Esp (2006-2014) name "Esp"bind "TAB" "+showscores"bi ...
- BZOJ 1176: [Balkan2007]Mokia
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 2012 Solved: 896[Submit][St ...
- ubuntu终端窗口最大化(不是全屏)
窗口最大化:ctrl+win窗+↑ 窗口还原:ctrl+win窗+↓ 这快捷键让人无语.好好的gnome被改造成unity,快捷键也改掉了.win窗+↑/↓为啥不用呢? 还有就是terminal的ta ...
- EventDispatcher 事件分发组件
引言 考虑这样一个问题,现在你想给为你的项目提供一个插件系统,插件可以添加一些方法,或者在某些方法执行之前或者之后做些事情,而不干扰其他插件.要实现这个系统,简单的单继承不是个好办法,即使多继承在PH ...
- Android Studio更新升级方法
自从2013 Google I/O大会之后,笔者就将android ide开发工具从eclipse迁移到Android Studio了,android studio一直在更新完善,为了与时俱进,我们当 ...
- ssl
在Java加密技术(八)中,我们模拟了一个基于RSA非对称加密网络的安全通信.现在我们深度了解一下现有的安全网络通信--SSL. 我们需要构建一个由CA机构签发的有效证书,这里我们使用上文中生 ...
- python 生成验证码
在工作中经常遇到一些验证码,这些是怎么生成的呢,今天我用Python编写了下 import randomcode = []for i in range(6): if i == random.randi ...
- [01] cocos2d-x开发环境搭建
cocos2d-x 是跨平台的游戏开发引擎,支持的平台有 ios , android , windows phone , web , tizen,windows等. 先来搭建开发环境,一般我们开发游戏 ...