题目

给你一个有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——最短路算法的更多相关文章

  1. Dijkstra 最短路算法(只能计算出一条最短路径,所有路径用dfs)

    上周我们介绍了神奇的只有五行的 Floyd 最短路算法,它可以方便的求得任意两点的最短路径,这称为"多源最短路".本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做&q ...

  2. Dijkstra最短路算法

    Dijkstra最短路算法 --转自啊哈磊[坐在马桶上看算法]算法7:Dijkstra最短路算法 上节我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最 ...

  3. Floyd最短路算法

    Floyd最短路算法 ----转自啊哈磊[坐在马桶上看算法]算法6:只有五行的Floyd最短路算法 暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计 ...

  4. Book 最短路算法

    用HDU2544整理一下最近学的最短路算法 1.Dijkstra算法 原理:集合S表示已经找到最短路径的点,d[]表示当前各点到源点的距离 初始时,集合里面只有源点,当每个点u进入集合S时,用d[u] ...

  5. 近十年one-to-one最短路算法研究整理【转】

    前言:针对单源最短路算法,目前最经典的思路即标号算法,以Dijkstra算法和Bellman-Ford算法为根本演进了各种优化技术和算法.针对复杂网络,传统的优化思路是在数据结构和双向搜索上做文章,或 ...

  6. 【啊哈!算法】算法7:Dijkstra最短路算法

    上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”.例如求下图 ...

  7. 【啊哈!算法】算法6:只有五行的Floyd最短路算法

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

  8. Comet OJ 热身赛(E题)(处理+最短路算法)

    dijkstra 已经提交 已经通过 42.86% Total Submission:189 Total Accepted:81 题目描述 Eagle Jump公司正在开发一款新的游戏.泷本一二三作为 ...

  9. 【最短路算法】Dijkstra+heap和SPFA的区别

    单源最短路问题(SSSP)常用的算法有Dijkstra,Bellman-Ford,这两个算法进行优化,就有了Dijkstra+heap.SPFA(Shortest Path Faster Algori ...

随机推荐

  1. maven(一)创建一个maven的web项目

    一.创建项目 1.Eclipse中用Maven创建项目 上图中Next 2.继续Next 3.选maven-archetype-webapp后,next 4.填写相应的信息,Packaged是默认创建 ...

  2. 【BZOJ 3223】 文艺平衡树

    [题目链接] 点击打开链接 [算法] 本题是splay区间操作的模板题 我们每个点的权值设为”当前在序列中的排名“,根据二叉排序树的性质,这棵树的中序遍历就是当前序列 如果我们要获得一段区间[l,r] ...

  3. kafka之四:Kafka集群搭建

    1.软件环境 1.linux一台或多台,大于等于2 2.已经搭建好的zookeeper集群 3.软件版本kafka_2.11-0.9.0.1.tgz 2.创建目录并下载安装软件 #创建目录 cd /o ...

  4. .NETFramework:HttpContext

    ylbtech-.NETFramework:HttpContext 1.返回顶部 1. #region 程序集 System.Web, Version=4.0.0.0, Culture=neutral ...

  5. vue 基本知识整理

    1 每个Vue.js应用都是通过构造函数Vue创建一个Vue的根实例 2 可以扩展Vue构造器,从而使用预定义选项创建可复用的组件构造器 所有的Vue.js组件其实都是被扩展的Vue实例 每一个VUE ...

  6. div 加滚动条的方法

    div 加滚动条的方法: <div style="position:absolute; height:400px; overflow:auto"></div> ...

  7. 容器云未来:Kubernetes、Istio 和 Knative

    导读 目前以Kubernetes为基础构建的容器生态逐渐完善,这其中Kubernetes.Istio.Knative三个独立项目被越来越多的人提及,并且已经开始尝试大规模落地实践,它们恰好构成了容器云 ...

  8. hdoj5805【模拟】

    BestCoder Round #86 B NanoApe Loves Sequence 题意: 中文题,题意就算了 思路: 弱的思路- 找一个最大,和第二大,第三大,标记下标(前面那个) ①:如果是 ...

  9. CF1059E Split the Tree(倍增)

    题意翻译 现有n个点组成一棵以1为根的有根树,第i个点的点权为wi,需将其分成若干条垂直路径使得每一个点当且仅当被一条垂直路径覆盖,同时,每条垂直路径长度不能超过L,点权和不能超过S,求最少需要几条垂 ...

  10. Adore

    (非公共题目) 问题描述 小 w 偶然间⻅到了一个 DAG.这个 DAG 有 m 层,第一层只有一个源点,最后一层只有一个汇点,剩下的每一层都有 k 个节点. 现在小 w 每次可以取反第 i(1 &l ...