NOI2014 魔法森林 day1t2 SPFA
这道题做法还是很多的,至少有人用最优性剪枝当场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的更多相关文章
- BZOJ3669 [Noi2014]魔法森林(SPFA+动态加边)
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- bzoj 3669: [Noi2014]魔法森林 -- 动点spfa
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MB 动点spfa Description 为了得到书法大家的真传,小E同学下定决心 ...
- 【BZOJ 3669】 3669: [Noi2014]魔法森林 (动态spfa)
3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N ...
- NOI2014 魔法森林
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 106 Solved: 62[Submit][Status] ...
- bzoj 3669: [Noi2014]魔法森林
bzoj 3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号 ...
- 洛谷 P2387 [NOI2014]魔法森林 解题报告
P2387 [NOI2014]魔法森林 题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2 ...
- bzoj 3669: [Noi2014]魔法森林 动态树
3669: [Noi2014]魔法森林 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 363 Solved: 202[Submit][Status] ...
- BZOJ 3669: [Noi2014]魔法森林( LCT )
排序搞掉一维, 然后就用LCT维护加边MST. O(NlogN) ------------------------------------------------------------------- ...
- BZOJ_3669_[Noi2014]魔法森林_LCT
BZOJ_3669_[Noi2014]魔法森林_LCT Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节 ...
随机推荐
- JS实现的随机乱撞的彩色圆球特效代码
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- iOS开发ARC机制下的内存管理技术要点
转载一篇: iOS开发ARC内存管理技术要点.ARC内存管理原则总结.iOS ARC内存管理总结 ARC内存管理机制 (一)ARC的判断准则: 只要没有任何一个强指针指向该对象,该对象就会被释放. ( ...
- Educational Codeforces Round 61 (Rated for Div. 2) D,F题解
D. Stressful Training 题目链接:https://codeforces.com/contest/1132/problem/D 题意: 有n台电脑,每台电脑都有初始电量ai,也有一个 ...
- Going Home POJ - 2195 费用流板子题
On a grid map there are n little men and n houses. In each unit time, every little man can move one ...
- 文件上传文件的权限--lnmp 环境配置,尤其整个项目复制过来动~~~
site_upload 需要是自己才建立动才会是root root 所有者:---不是root : root 上传不了文件,不是 777 就都可以上传的,也要看看是谁建立的文件夹: 打包 ...
- Java IO------------------BIO(同步阻塞)、NIO1.0(多路复用)、NIO2.0(AIO,非阻塞)
1. BIO JDK5之前, JDK的IO模式只有BIO(同步阻塞)问题: 因为阻塞的存在, 需对每个请求开启一个线程. 过多的线程切换影响操作系统性能解决: 使用线程池, 处理不过来的放入队列, 再 ...
- python实现堆栈、队列
一.利用python列表实现堆栈和队列 堆栈: 堆栈是一个后进先出的数据结构,其工作方式就像生活中常见到的直梯,先进去的人肯定是最后出. 我们可以设置一个类,用列表来存放栈中的元素的信息,利用列表的a ...
- mysql创建用户,并授权
1.创建用户 CREATE USER 'username'@'host' IDENTIFIED BY 'password'; host分下列3种情况:'%' - 所有情况都能访问‘localhost’ ...
- 快速排序Quick sort
快速排序Quick sort 原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归 ...
- Linux下Tomcat重启脚本
我们重启Tomcat服务的时候,Tomcat自带的shutdown.sh脚本有时并不能真正杀死进程,经常需要我们用“kill -9 pid”的方式来杀死进程. 下面的脚本可以简化我们的操作,执行可杀死 ...