CCF-CSP题解 201703-4 地铁修建
求1-n最长边最小的路径。
最短路变形。dis值向后延申的方式是:$$dis[j]=min(dis[j],max(dis[i],w(i,j))$$
显然满足dijkstra贪心的选择方式。spfa也当然可以用。
写上三种方式,就当是模板好了。
spfa
复杂度:\(O(kE)/O(VE)\)
spfa的主要思想是不断松弛。注意spfa的更新策略,先更新\(dis\)值,再根据\(vis\)判断是否丢到\(queue\)中。
#include <bits/stdc++.h>
const int maxn = 100000;
const int maxm = 200000;
using namespace std;
int n, m;
int to[maxm * 2 + 10];
int w[maxm * 2 + 10];
int nex[maxm * 2 + 10];
int head[maxn + 10], cnt = 0;
void addEdge(int a, int b, int c)
{
to[cnt] = b; w[cnt] = c;
nex[cnt] = head[a]; head[a] = cnt++;
to[cnt] = a; w[cnt] = c;
nex[cnt] = head[b]; head[b] = cnt++;
}
int vis[maxn + 10];
int dis[maxn + 10];
void spfa()
{
queue<int> q;
dis[1] = 0;
q.push(1);
vis[1] = 1;
while (!q.empty())
{
int x = q.front(); q.pop();
vis[x] = 0;
// printf("current node: %d %d\n", x, dis[x]);
for (int i = head[x]; i != -1; i = nex[i])
{
int l = to[i];
if (max(dis[x], w[i]) < dis[l])
{
dis[l] = max(dis[x], w[i]);
if (!vis[l])
{
q.push(l);
vis[l] = 1;
}
}
}
}
}
int main()
{
scanf("%d%d", &n, &m);
memset(head, -1, sizeof(head));
for (int i = 1, a, b, c; i <= m; i++)
{
scanf("%d%d%d", &a, &b, &c);
addEdge(a, b, c);
}
memset(vis, 0, sizeof(vis));
memset(dis, 0x3f, sizeof(dis));
spfa();
printf("%d\n", dis[n]);
return 0;
}
dijkstra
会超时。
复杂度:\(O(V^2)\)
dijkstra的主要思想是一共\(V\)次贪心的选择当前未确定点中\(dis\)值最小的那一个确定。
#include <bits/stdc++.h>
const int inf = 0x3f3f3f3f;
const int maxn = 100000;
const int maxm = 200000;
using namespace std;
int n, m;
int to[maxm * 2 + 10];
int w[maxm * 2 + 10];
int nex[maxm * 2 + 10];
int head[maxn + 10], cnt = 0;
void addEdge(int a, int b, int c)
{
to[cnt] = b; w[cnt] = c;
nex[cnt] = head[a]; head[a] = cnt++;
to[cnt] = a; w[cnt] = c;
nex[cnt] = head[b]; head[b] = cnt++;
}
int done[maxn + 10];
int dis[maxn + 10];
void dijkstra()
{
dis[1] = 0;
for (int i = 1; i <= n; i++)
{
int x = 0, mmin = inf;
for (int j = 1; j <= n; j++)
{
if (!done[j] && dis[j] < mmin)
mmin = dis[x = j];
}
done[x] = 1;
for (int j = head[x]; j != -1; j = nex[j])
{
int l = to[j];
dis[l] = min(dis[l], max(dis[x], w[j]));
}
}
}
int main()
{
scanf("%d%d", &n, &m);
memset(head, -1, sizeof(head));
for (int i = 1, a, b, c; i <= m; i++)
{
scanf("%d%d%d", &a, &b, &c);
addEdge(a, b, c);
}
memset(done, 0, sizeof(done));
memset(dis, 0x3f, sizeof(dis));
dijkstra();
printf("%d\n", dis[n]);
return 0;
}
heap_dijkstra
复杂度(stl优先队列实现,由于每条边最多被访问一次,堆中最多会有\(E\)个节点):\(O(ElogE)\),当图趋于完全图时,复杂度趋于\(O(V^2logV)\),应当使用一般实现的dijkstra算法。
堆优化dijkstra,主要思想是利用堆加速每一次值最小(未确定)的点的选择。实际实现略有不同,所以复杂度并非\(O(VlogV)\)。
#include <bits/stdc++.h>
const int inf = 0x3f3f3f3f;
const int maxn = 100000;
const int maxm = 200000;
using namespace std;
int n, m;
int to[maxm * 2 + 10];
int w[maxm * 2 + 10];
int nex[maxm * 2 + 10];
int head[maxn + 10], cnt = 0;
void addEdge(int a, int b, int c)
{
to[cnt] = b; w[cnt] = c;
nex[cnt] = head[a]; head[a] = cnt++;
to[cnt] = a; w[cnt] = c;
nex[cnt] = head[b]; head[b] = cnt++;
}
struct tNode
{
int d, u; // estimated dis, id of vertex
tNode(int dd, int uu): d(dd), u(uu){}
bool operator < (const tNode &y) const
{
return d > y.d;
}
};
int done[maxn + 10];
int dis[maxn + 10];
void heap_dijkstra()
{
priority_queue<tNode> q;
dis[1] = 0;
q.push(tNode(0, 1));
while (!q.empty())
{
tNode x = q.top(); q.pop();
int u = x.u;
if (done[u])
continue;
done[u] = 1;
for (int i = head[u]; i != -1; i = nex[i])
{
int l = to[i];
if (dis[l] > max(dis[u], w[i]))
{
dis[l] = max(dis[u], w[i]);
q.push(tNode(dis[l], l));
}
}
}
}
int main()
{
scanf("%d%d", &n, &m);
memset(head, -1, sizeof(head));
for (int i = 1, a, b, c; i <= m; i++)
{
scanf("%d%d%d", &a, &b, &c);
addEdge(a, b, c);
}
memset(done, 0, sizeof(done));
memset(dis, 0x3f, sizeof(dis));
heap_dijkstra();
printf("%d\n", dis[n]);
return 0;
}
CCF-CSP题解 201703-4 地铁修建的更多相关文章
- CCF CSP 201703-4 地铁修建
博客中的文章均为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201703-4 地铁修建 问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n ...
- CCF CSP 201703
CCF CSP 2017·03 做了一段时间的CCF CSP试题,个人感觉是这样分布的 A.B题基本纯暴力可满分 B题留心数据范围 C题是个大模拟,留心即可 D题更倾向于图论?(个人做到的D题基本都是 ...
- ccf 201703-4 地铁修建(95)(并查集)
ccf 201703-4 地铁修建(95) 使用并查集,将路径按照耗时升序排列,依次加入路径,直到1和n连通,这时加入的最后一条路径,就是所需要修建的时间最长的路径. #include<iost ...
- CSP 201703-4 地铁修建 最小生成树+并查集
地铁修建 试题编号: 201703-4 试题名称: 地铁修建 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力, ...
- CSP 201703-4 地铁修建【最小生成树+并查集】
问题描述 试题编号: 201703-4 试题名称: 地铁修建 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市 ...
- CCF(地铁修建):向前星+dijikstra+求a到b所有路径中最长边中的最小值
地铁修建 201703-4 这题就是最短路的一种变形,不是求两点之间的最短路,而是求所有路径中的最长边的最小值. 这里还是使用d数组,但是定义不同了,这里的d[i]就是表示从起点到i的路径中最长边中的 ...
- CCF CSP 201412-4 最优灌溉
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201412-4 最优灌溉 问题描述 雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖 ...
- CCF CSP 201703-3 Markdown
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201703-3 Markdown 问题描述 Markdown 是一种很流行的轻量级标记语言(l ...
- CCF CSP 201312-3 最大的矩形
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201312-3 最大的矩形 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i( ...
- CCF CSP 201609-3 炉石传说
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201609-3 炉石传说 问题描述 <炉石传说:魔兽英雄传>(Hearthston ...
随机推荐
- Condition对象以及ArrayBlockingQueue阻塞队列的实现(使用Condition在队满时让生产者线程等待, 在队空时让消费者线程等待)
Condition对象 一).Condition的定义 Condition对象:与锁关联,协调多线程间的复杂协作. 获取与锁绑定的Condition对象: Lock lock = new Reentr ...
- Python练习100题
Python练习100题 题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? #Filename:001.py cnt = 0#count the sum of res ...
- 关于Java中2.0-1.1!=0.9的问题
关于Java中2.0-1.1!=0.9的问题 问题引出: 在<Java核心技术>中关于浮点数值计算部分提到,System.out.println(2.0-1.1)这条语句并不是想当然的0. ...
- socket解决编码解码问题
MySocket类: import socket class MySocket(socket.socket): # 继承自socket文件中的socket类,此时socket就是父类 def __in ...
- 一个HTML5培训班毕业生的找工作随笔
昨天刚参加完一个面试,通过了.写个随笔记录一下. 先介绍一下背景. 我是今年十月份的时候从某个培训机构的HTML5 Web前端培训班毕业的,是一个刚进入IT行业的新人. 本人毕业于某三流学校,在参加培 ...
- 计蒜客T1846AC记
查看原题: 原题地址 初步思路: 采用贪心法求解,贪心策略如下: 排序,优先买最便宜的. 累加总数ans 初步代码: (楼主评语:其实其他地方的编程实现不太重要,贪心策略才是问题) #include ...
- Linux的用户切换、修改用户的用户名和密码
一.用户切换 "$":普通用户提示符 "#":root用户提示符 1.普通用户到root: 方式一:命令:su然后输入root密码 此种方式只是切换了root ...
- 01 jQuery配置、jQuery语法结构、jQuery对象与DOM对象的互相转换
配置jQuery环境 下载jQuery 官网:jquery.com 学习或开发建议选择未压缩版,便于学习,发布建议选择压缩版,便于用户极速体验(点击下载若出现的是代码页 面,Ctrl+A全选复制 ...
- oracle 触发器(自增写法)
触发器trigger 触发器我们也可以认为是存储过程,是一种特殊的存储过程. 存储过程:有输入参数和输出参数,定义之后需要调用 触发器:没有输入参数和输出参数,定义之后无需调用,在适当的时候会自动执行 ...
- 【JavaEE】之MyBatis逆向工程的使用
MyBatis逆向工程可以方便的从数据库中将表自动映射到JAVA POJO类,并同时生成Mapper.xml和Mapper接口,方便实用.下面介绍一下逆向工程的使用方法. 使用逆向工程,我们最好是新建 ...