题目

给你一个有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. PostgreSQ 连接问题 FATAL: no pg_hba.conf entry for host

    PostgreSQ数据库为了安全,它不会监听除本地以外的所有连接请求,当用户通过JDBC访问是,会报一些如下的异常: org.postgresql.util.PSQLException: FATAL: ...

  2. Bootstrap-CL:字体图标(Glyphicons)

    ylbtech-Bootstrap-CL:字体图标(Glyphicons) 1.返回顶部 1. Bootstrap 字体图标(Glyphicons) 本章将讲解字体图标(Glyphicons),并通过 ...

  3. EasyUI 表格点击右键添加或刷新 绑定右键菜单

    例1 在HTML页面中设置一个隐藏的菜单(前提是已经使用封装的Easyui) 代码: <div id="contextMenu_jygl" class="easyu ...

  4. UVaLive 3401 Colored Cubes (暴力)

    题意:给定n个立方体,让你重新涂尽量少的面,使得所有立方体都相同. 析:暴力求出每一种姿态,然后枚举每一种立方体的姿态,求出最少值. 代码如下: #pragma comment(linker, &qu ...

  5. cardboard sdk for unity 系统分析 - 属性行为分析CardBoard类

    一.CardBoard类是个单例类,全局只有一个CardBoard对像且在需要时才生成: CardBoard中主要使用了BaseVRDevice device这个对像,而这个对像也是单例类BaseVR ...

  6. C++笔试题库之编程、问答题 150~200道

    151.写出判断ABCD四个表达式的是否正确, 若正确, 写出经过表达式中 a的值 int a = 4; (A)a += (a++); (B) a += (++a) ;(C) (a++) += a;( ...

  7. Oracle更新数据为MD5加密数据

    业务场景:在做安全等保问题,需要将原来保存的用户明文密码改成md5加密的密文密码,数据库是Oracle的 首先Oracle要管理员账号登录才可以调md5函数,具体函数是DBMS_OBFUSCATION ...

  8. 黑客攻防技术宝典web实战篇:攻击会话管理习题

    猫宁!!! 参考链接:http://www.ituring.com.cn/book/885 随书答案. 1. 登录一个应用程序后,服务器建立以下 cookie:Set-cookie: sessid=a ...

  9. P1223 [小数据版]边权差值最小的生成树

    这道题和最小生成树kruskal的代码几乎相同,只不过不一定是最小生成树,所以不一定从最短的边开始做生成树:所以将每一条边分别作为起点,然后枚举就行了...... #include <bits/ ...

  10. php分页例子实现读取mysql数据分页显示

    以下代码是PHP分页案例,测试通过,主要是PHP+mysql实现分页,代码来处百度空间,有兴趣看的话可以了解一下PHP是如何分页的? <?php $link = mysql_connect(&q ...