<题目链接>

题目大意:

n个点,m条边的无向图,现在需要删除一些边,使得剩下的边数不能超过K条。1点为起点,如果1到 i 点的最短距离与删除边之前的最短距离相同,则称 i 为 "good vertice",现在问你如果要使 "good vertice"最多,需要留下多少条边,并且输出这些边的序号。

解题分析:

我们最多只能留k条边 (或者是n-1条边,因为经过Dijkstra松弛后,其实只需要n-1条边就能使起点到所有点的最短距离仍然为未删边时的最短距离,想一下Dijkstra的松弛过程就能明白)。

那如何留下的 "good vertice" 最多呢?其实 "good vertice" 就是指我们尽量不要破坏原来的最短路径,那些越先通过Dijkstra松弛得到最短路的点的最短路径所需的维护的路径数量是最少的,所以我们贪心的将松弛的前K个点的之前的路劲记录即可,这样延伸出的连通块能够让其中所有的点到起点的最短距离等于原始的最短距离,同时他们所需维护的路径还是尽可能的少的。

 #include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std; #define M int(3e5+10)
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define pb push_back
#define clr(a,b) memset(a,b,sizeof(a))
#define INF ll(1e18)
typedef long long ll;
int cnt,head[M],loc[M];
bool vis[M];
vector<int>vec;
int n,m,k; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<'' || ch>'') f|=(ch=='-'),ch=getchar();
while (ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
}
struct Edge{
int to,ord,next;
ll val;
}edge[M<<]; struct Node{
int ord;ll dist;
Node(int _ord=,ll _dist=):ord(_ord),dist(_dist){}
bool operator < (const Node &tmp)const {
return dist>tmp.dist;
}
}d[M];
void init(){
cnt=;clr(head,-);
}
void addedge(int u,int v,ll w,int c){
edge[++cnt].to=v;edge[cnt].val=w,edge[cnt].ord=c;
edge[cnt].next=head[u];head[u]=cnt;
}
void Dijkstra(){
priority_queue<Node>q;
for(int i=;i<=n;i++)
d[i].dist=INF,d[i].ord=i,vis[i]=false;
d[].dist=;q.push(d[]);
while(q.size()){
int u=q.top().ord;q.pop();
if(vis[u])continue;
vis[u]=true;vec.pb(loc[u]);
if(vec.size()==k+)return ; //因为起点的前一条边没有意义,所以这里是k+1结束
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;ll cost=edge[i].val;
if(!vis[v]&&d[v].dist>d[u].dist+cost){
d[v].dist=d[u].dist+cost;
loc[v]=edge[i].ord; //记录这个点在 1--->v的最短路的最后一条边
q.push(d[v]);
}
}
}
}
int main(){
read(n);read(m);read(k);init();
rep(i,,m){
int u,v;ll w;
read(u);read(v);read(w);
addedge(u,v,w,i);addedge(v,u,w,i);
}
k=min(k,n-); //k与(n-1)进行比较
Dijkstra();printf("%d\n",k);
rep(i,,k)i==k?printf("%d\n",vec[i]):printf("%d ",vec[i]); //因为起点的前一条边没有意义,所以这里从1开始输出
}

2019-02-12

Codeforces 1076D Edge Deletion 【最短路+贪心】的更多相关文章

  1. Codeforces 1076D Edge Deletion(最短路树)

    题目链接:Edge Deletion 题意:给定一张n个顶点,m条边的带权无向图,已知从顶点1到各个顶点的最短路径为di,现要求保留最多k条边,使得从顶点1到各个顶点的最短距离为di的顶点最多.输出m ...

  2. 【CF1076D】Edge Deletion 最短路+贪心

    题目大意:给定 N 个点 M 条边的无向简单联通图,留下最多 K 条边,求剩下的点里面从 1 号顶点到其余各点最短路大小等于原先最短路大小的点最多怎么构造. 题解:我们可以在第一次跑 dij 时直接采 ...

  3. Edge Deletion CodeForces - 1076D(水最短路)

    题意: 设从1到每个点的最短距离为d,求删除几条边后仍然使1到每个点的距离为d,使得剩下的边最多为k 解析: 先求来一遍spfa,然后bfs遍历每条路,如果d[v] == d[u] + Node[i] ...

  4. 1076D Edge Deletion 【最短路】

    题目:戳这里 题意:求出1到所有点的最短路径后,把边减到小于等于k条,问保留哪些边可以使仍存在的最短路径最多. 解题思路:这题就是考求最短路的原理.比如dijkstra,用优先队列优化后存在队列中的前 ...

  5. Codeforces Round #303 (Div. 2) E. Paths and Trees 最短路+贪心

    题目链接: 题目 E. Paths and Trees time limit per test 3 seconds memory limit per test 256 megabytes inputs ...

  6. Codeforces 437C The Child and Toy(贪心)

    题目连接:Codeforces 437C  The Child and Toy 贪心,每条绳子都是须要割断的,那就先割断最大值相应的那部分周围的绳子. #include <iostream> ...

  7. Codeforces Round #546 (Div. 2) D 贪心 + 思维

    https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则, ...

  8. Educational Codeforces Round 54 (Rated for Div. 2) D:Edge Deletion

    题目链接:http://codeforces.com/contest/1076/problem/D 题意:给一个n个点,m条边的无向图.要求保留最多k条边,使得其他点到1点的最短路剩余最多. 思路:当 ...

  9. Codeforces Round #303 (Div. 2)(CF545) E Paths and Trees(最短路+贪心)

    题意 求一个生成树,使得任意点到源点的最短路等于原图中的最短路.再让这个生成树边权和最小. http://codeforces.com/contest/545/problem/E 思路 先Dijkst ...

随机推荐

  1. Java调用oracle存储过程通过游标返回临时表数据

    注:本文来源于 <  Java调用oracle存储过程通过游标返回临时表数据   > Java调用oracle存储过程通过游标返回临时表数据 项目开发过程中,不可避免的会用到存储过程返回结 ...

  2. python使用 HTMLTestRunner.py生成测试报告

    HTMLTestRunner.py python 2版本 下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html 使用时,先建立一个”PyDe ...

  3. 用gojs写的流程图demo

    领导要求,可以展开收缩子级,但是子级可以有多个父级,一开始用的dagre-d3.js,但是功能不是太全,无意中看到gojs,感觉还不错,所以拿来改了改... 代码地址:https://github.c ...

  4. 添加按钮 table增加一行 删减按钮 table去掉一行

    需求描述:做的一个AA新增功能,同时可以为这个即将新增的AA添加内容,而且AA的内容默认展示一行列表,点击添加按钮后出现下一行列表 解决思路:页面首先展示一个表头和列表的一行,作为默认展示的一行列表, ...

  5. laravel 注入那点事

    public function delete(Group $groupId, Post $postId) { $postId->delete(); return response()->j ...

  6. 状态压缩dp小结

    最近一段时间算是学了一些状态压缩的题目,在这里做个小结吧 首先是炮兵布阵类题目,这类题目一开始给定一个矩形,要求在上面放置炮兵,如果在一格放了炮兵那么周围的某些格子就不能放炮兵,求最大能放置炮兵的数量 ...

  7. 优先选择nullptr而不是0和NULL

    我们知道:0是一个int,而不是一个指针.如果C++在一个只有指针才能够使用的上下文中发现它只有一个0,那么它会勉强将0解释成空指针,但那时一种倒退行为.C++的主要方针是0就是一个int,而不是指针 ...

  8. 将眼底图片生成的txt文件进行格式化处理

    # -*- coding: utf-8 -*- """ 将图片转换生成的txt文件进行格式化处理 """ import os import ...

  9. 任务超时退出的方法 C#

    超出时间方法退出.防止卡住. 方法: private static bool ImportTaskTimeout(Action method, int hours) { try { var task ...

  10. Java+selenium之WebDriver的常用方法封装(八)

    总结:WEB UI自动化测试一般采用 POP(面向页面编程),自动化测试框架分三层,有时如果页面如果太多,不好管理,可以面向控件编程,即把控件当作页面,毕竟控件是有限的,所以封装页面的代码量会少很多, ...