Codeforces 1076D——最短路算法
题目
给你一个有n个顶点、m条边的无向带权图。需要擦除一些边使得剩余的边数不超过k,如果一个点在原始图到顶点1的最短距离为d,在删边后的图中到顶点的最短距离仍是d,则称这种点是 good。问如何删边,使得 good点最多。
分析
首先调用最短路算法求各点到顶点1的最短距离,同时记录下每点在最短路上的前一个顶点。然后从顶点1出发搜索一个大小为k的联通块即可(如果够k个)
代码
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std; typedef long long ll; const ll INF = (ll) << ;
const int maxv = + ; //最大顶点数
const int maxe = * + ; //最大边数
ll dis[maxv]; //源到各顶点的最短距离
int vis[maxv]; //记录是否被收录,用来代替集合S
int head[maxv]; //采用链式前向星建图
int pre[maxv]; //最短路树,记录前一个节点 vector<int>ans; //记录答案
int n, m, k; //顶点数、边数、最大保留的边数 struct Node
{
int u;
ll d; //该节点的编号与距离
bool operator < (const Node x) const
{
return d > x.d;
}
}; struct Edge
{
int to, w, next;
}edge[maxe]; inline void addedge(int u, int v, int w, int id)
{
edge[id].to = v;
edge[id].w = w;
edge[id].next = head[u];
head[u] = id;
}
//s为起点
void Dijsktra(int s)
{
priority_queue<Node>q; //取出集合T中的最小值
memset(vis, , sizeof(vis));
memset(pre, -, sizeof(pre));
//memset(dis, INF, sizeof(dis)); //与邻接矩阵不同,这里初始化为INF就可以,原因自己想
for (int i = ; i <= n; i++) dis[i] = INF; dis[s] = ;
q.push(Node{ s, dis[s] });
while (!q.empty())
{
Node x = q.top(); q.pop();
int u = x.u; if (vis[u]) continue; vis[u] = true;
for (int i = head[u]; i != -; i = edge[i].next) //松弛与u直接相邻的顶点
{
int v = edge[i].to;
int w = edge[i].w;
if (!vis[v] && dis[u] + w < dis[v])
{
dis[v] = dis[u] + w;
pre[v] = u; //记录最短路树的父节点
q.push(Node{ v,dis[v] });
}
}
}
} //从s出发找出最短路树上的k个节点(不到k个就是全部节点)
void bfs(int s)
{
queue<int>q;
q.push(s);
while (!q.empty())
{
int u = q.front(); q.pop();
for (int e = head[u]; e != -; e = edge[e].next)
{
int v = edge[e].to;
if (pre[v] == u && ans.size() < k)
{
q.push(edge[e].to);
ans.push_back(e / + ); //无向边建图时存了两遍,真实序号位e/2+1
}
}
if (ans.size() >= k) break;
}
} int main()
{
while (scanf("%d%d%d",&n,&m,&k) == )
{
memset(head, -, sizeof(head));
int id = ;
for (int i = ; i < m; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
addedge(u, v, w,id++); addedge(v, u, w,id++);
} Dijsktra(); ans.clear();
bfs();
int cnt = ans.size();
printf("%d\n", cnt);
for (int i = ; i < cnt; i++)
printf("%d%c", ans[i], i == cnt - ? '\n' : ' ');
}
return ;
}
参考链接:https://blog.csdn.net/SparkFucker/article/details/84024243
Codeforces 1076D——最短路算法的更多相关文章
- Dijkstra 最短路算法(只能计算出一条最短路径,所有路径用dfs)
上周我们介绍了神奇的只有五行的 Floyd 最短路算法,它可以方便的求得任意两点的最短路径,这称为"多源最短路".本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做&q ...
- Dijkstra最短路算法
Dijkstra最短路算法 --转自啊哈磊[坐在马桶上看算法]算法7:Dijkstra最短路算法 上节我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最 ...
- Floyd最短路算法
Floyd最短路算法 ----转自啊哈磊[坐在马桶上看算法]算法6:只有五行的Floyd最短路算法 暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计 ...
- Book 最短路算法
用HDU2544整理一下最近学的最短路算法 1.Dijkstra算法 原理:集合S表示已经找到最短路径的点,d[]表示当前各点到源点的距离 初始时,集合里面只有源点,当每个点u进入集合S时,用d[u] ...
- 近十年one-to-one最短路算法研究整理【转】
前言:针对单源最短路算法,目前最经典的思路即标号算法,以Dijkstra算法和Bellman-Ford算法为根本演进了各种优化技术和算法.针对复杂网络,传统的优化思路是在数据结构和双向搜索上做文章,或 ...
- 【啊哈!算法】算法7:Dijkstra最短路算法
上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”.例如求下图 ...
- 【啊哈!算法】算法6:只有五行的Floyd最短路算法
暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有 ...
- Comet OJ 热身赛(E题)(处理+最短路算法)
dijkstra 已经提交 已经通过 42.86% Total Submission:189 Total Accepted:81 题目描述 Eagle Jump公司正在开发一款新的游戏.泷本一二三作为 ...
- 【最短路算法】Dijkstra+heap和SPFA的区别
单源最短路问题(SSSP)常用的算法有Dijkstra,Bellman-Ford,这两个算法进行优化,就有了Dijkstra+heap.SPFA(Shortest Path Faster Algori ...
随机推荐
- 用python写windows服务
用python写windows服务(1) 以python2.5 为例需要软件 * python 2.5 * pywin32(与2.5 版本相匹配的) Service Control Ma ...
- ASP.NET Core MVC 2.x 全面教程_ASP.NET Core MVC 08. 输入Model和防止重复Post
通过action的参数传入一个model 通过input的name属性和model属性对应上 通常是使用Http post去做 快速创建了这个Action 这个Action很简单我们只需要返回View ...
- 一个获取google chrome扩展crx文件信息的PHP操作类
此类中实现了从crx文件获取扩展的Appid.获取manifest.json文件内容.将crx文件转换为一般zip文件 代码如下: <?php class CrxParserException ...
- JAVA基础-面向对象07
一.代码块 1. 含义: 就是使用大括号括起来的一段代码 格式 { 代码: } 2.静态代码块 格式 static{ 代码: } 书写位置: 直接书写在类中成员位置: 怎么执行呢? 在类加载的最后一步 ...
- 洛谷 - P4452 - 航班安排 - 费用流
https://www.luogu.org/problemnew/show/P4452 又一道看题解的费用流. 注意时间也影响节点,像题解那样建边就少很多了. #include<bits/std ...
- ZOJ1004 DFS基础
这道题一看就觉得是DFS,但是,不对,还有栈,这就有点难办了. DFS+栈一波新姿势. 在DFS里面用栈的思想. DFS主要就是搜下去, 然后前一个状态标记,搜完以后,还是要保持前一个状态. 然后就把 ...
- PJzhang:微信公众号短连接与微信好友验证
猫宁!!! 参考链接:https://mp.weixin.qq.com/s/LPuYrDEyEXHyhcK3_HokSg 之前看到他们有人把微信公众号文章的长链接转为短链接,很受用,百度搜索一下方法, ...
- (七)SpringBoot使用PageHelper分页插件
二:添加PageHelper依赖 <dependency> <groupId>com.github.pagehelper</groupId> <artifac ...
- Raphael.js改变元素层叠顺序
Raphael.js 元素(Element)改变层叠顺序,Raphael.js是一个矢量绘图库兼容svg和vml.初学时感觉css的z-index能搞定,结果是不支持,不过矢量绘图符合dom标准.可以 ...
- Linux源码编译处理
1. 解决依赖问题 查询需要的依赖软件,提前安装好若使用命令行安装,一般使用默认路径:使用源码安装,则自定义安装路径,后续可能需要进行路径配置PS:可能需要在Makefile等配置文件中添加相关库文件 ...