这道题做法还是很多的,至少有人用最优性剪枝当场A掉了。我只有50分的暴力分(写丑了),SB我不会LCT,先写一下SPFA的神思路做法(说白了还是我SB),LCT以后定补。ORZ想出来的人(hq大神)。最近总感觉考试时没有发挥出全力,考完后一想才发现做法其实还是很好想的。

题意:给一个节点n边m的图,每条边有两个权值a和b,要从1选择两个数x,y出发通过\(a \le x,\ \ b \le y\)的边走到n,求最小的x+y。

想想What's SPFA?最短路?但是我们可以利用松弛操作找到特点两点间的边的最大值。用dis数组来保存从1点到当前点的路径上最大的b称为当前点花费b。做法的精妙之处在于:我们可以从小到大枚举x,之前能到达的点,现在仍然能到达,所以不用管x;如果SPFA时不清空dis数组,里面保存的就是在之前的较小的x的情况下能走到的点的花费b,现在有可能会通过走新边来减小b,新边就是权值恰好为a的边,每次取有这样的边的点进行SPFA即可。

真是一道巧妙的题!

 //{HEADS
#define FILE_IN_OUT
#define debug
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <complex>
#include <string>
#define REP(i, j) for (int i = 1; i <= j; ++i)
#define REPI(i, j, k) for (int i = j; i <= k; ++i)
#define REPD(i, j) for (int i = j; 0 < i; --i)
#define STLR(i, con) for (int i = 0, sz = con.size(); i < sz; ++i)
#define STLRD(i, con) for (int i = con.size() - 1; 0 <= i; --i)
#define CLR(s) memset(s, 0, sizeof s)
#define SET(s, v) memset(s, v, sizeof s)
#define mp make_pair
#define pb push_back
#define PL(k, n) for (int i = 1; i <= n; ++i) { cout << k[i] << ' '; } cout << endl
#define PS(k) STLR(i, k) { cout << k[i] << ' '; } cout << endl
using namespace std;
#ifdef debug
#ifndef ONLINE_JUDGE
const int OUT_PUT_DEBUG_INFO = ;
#endif
#endif
#ifdef ONLINE_JUDGE
const int OUT_PUT_DEBUG_INFO = ;
#endif
#define DG if(OUT_PUT_DEBUG_INFO)
typedef long long LL;
typedef double DB;
typedef pair<int, int> i_pair;
const int INF = 0x3f3f3f3f;
//} const int maxn = + ;
const int maxm = + ;
const int maxe = maxm * ;
/*{ 前向星*/
struct Edge {
int edge;
int head[maxn], to[maxe], next[maxe], la[maxe], lb[maxe];
Edge() {
edge = ;
memset(head, -, sizeof head);
}
void addedge(int u, int v, int a, int b) {
to[edge] = v;
next[edge] = head[u];
la[edge] = a;
lb[edge] = b;
head[u] = edge++;
}
}E;
/*}*/
int n, m; int dis[maxn];
queue<int> Q;
vector<int> p[maxn];
bitset<maxn> vis; void spfa(int u, int a) {
Q.push(u);
vis.reset();
vis[u] = ;
while(!Q.empty()) {
int v = Q.front(); Q.pop();
vis[v] = ;
for(int i = E.head[v]; i != -; i = E.next[i]) {
if(E.la[i] <= a && max(dis[v], E.lb[i]) < dis[E.to[i]]) {
dis[E.to[i]] = max(dis[v], E.lb[i]);
if(!vis[E.to[i]]) {
Q.push(E.to[i]);
vis[E.to[i]] = ;
}
}
}
}
} int main() {
//FILE_INIT("forest");
freopen("forest.in", "r", stdin);
freopen("forest.out", "w", stdout); scanf("%d%d", &n, &m);
int Max = -INF;
REP(i, m) {
int u, v, a, b;
scanf("%d%d%d%d", &u, &v, &a, &b);
E.addedge(u, v, a, b);
E.addedge(v, u, a, b);
p[a].pb(u);
p[a].pb(v);
Max = max(Max, a);
}
int ans = INF;
SET(dis, INF);
dis[] = ;
REP(i, Max) {
STLR(j, p[i]) {
spfa(p[i][j], i);
}
if(dis[n] != INF) {
ans = min(ans, dis[n] + i);
}
}
if(ans == INF) {
printf("%d\n", -);
} else {
printf("%d\n", ans);
} return ;
}

NOI2014 魔法森林 day1t2 SPFA的更多相关文章

  1. BZOJ3669 [Noi2014]魔法森林(SPFA+动态加边)

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  2. bzoj 3669: [Noi2014]魔法森林 -- 动点spfa

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MB 动点spfa Description 为了得到书法大家的真传,小E同学下定决心 ...

  3. 【BZOJ 3669】 3669: [Noi2014]魔法森林 (动态spfa)

    3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N ...

  4. NOI2014 魔法森林

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 106  Solved: 62[Submit][Status] ...

  5. bzoj 3669: [Noi2014]魔法森林

    bzoj 3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号 ...

  6. 洛谷 P2387 [NOI2014]魔法森林 解题报告

    P2387 [NOI2014]魔法森林 题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2 ...

  7. bzoj 3669: [Noi2014]魔法森林 动态树

    3669: [Noi2014]魔法森林 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 363  Solved: 202[Submit][Status] ...

  8. BZOJ 3669: [Noi2014]魔法森林( LCT )

    排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...

  9. BZOJ_3669_[Noi2014]魔法森林_LCT

    BZOJ_3669_[Noi2014]魔法森林_LCT Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节 ...

随机推荐

  1. 关于springmvc下服务器文件打包成zip格式下载功能

    关于springmvc下服务器文件打包成zip格式下载功能 2016年09月21日 11:22:14 toxic_guantou 阅读数:5731更多 个人分类: 技术点存储   版权声明:本文为博主 ...

  2. java访问Https服务的客户端示例

    关于证书 1.每个人都可以使用一些证书生成工具为自己的https站点生成证书(比如JDK的keytool),大家称它为“自签名证书”,但是自己生成的证书是不被浏览器承认的,所以浏览器会报安全提示,要求 ...

  3. HDU 5538 (水不水?)

    House Building Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) ...

  4. Samba共享传输大文件(ex:1G)失败的问题

    1:问题描述 1.1 基本信息 遇见这样一个bug,路由器有USB share的功能,可将U盘内的文件通过samba和LAN端PC机中文件进行共享,测试发现小文件可正常共享,一旦文件大了(比如1G左右 ...

  5. CSS3知识之立方体动画效果

    效果图:

  6. maven项目执行run as/maven install时提示找不到包

    选中项目,右键 右键项目->MAVEN->Update Project,如下图 点击ok,clean相关项目,再打包.如果还是不行看一下你jdk 的版本和你编译的版本是否一致

  7. ZooKeeper管理员指南(九)

    部署 这部分包含了部署ZooKeeper的信息和覆盖这些话题 系统要求 集群(多服务)安装 单服务和开发者安装 前两部分假定你对在例如数据中心的生产环境安装ZooKeeper有兴趣.最后一部分包含你在 ...

  8. oracle 存储过程 技巧

    我们在进行pl/sql编程时打交道最多的就是存储过程了.存储过程的结构是非常的简单的,我们在这里除了学习存储过程的基本结构外,还会学习编写存储过程时相关的一些实用的知识.如:游标的处理,异常的处理,集 ...

  9. windows 安装elk日志系统

    1.前往https://www.elastic.co官网下载对应的elasticsearch .kibana和logstash他们的版本号一致. 2.elasticsearch 解压后前往bin文件下 ...

  10. Java面试题整理二

    一.io有几种流? 有两种流:字节流和字符流. 字节流继承自inputstream和outstream. 字符流继承自write和read. 二.Jdbc的开发流程? JDBC编程的六个步骤: 1)加 ...