Codeforces 1076D Edge Deletion 【最短路+贪心】
<题目链接>
题目大意:
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 【最短路+贪心】的更多相关文章
- Codeforces 1076D Edge Deletion(最短路树)
		
题目链接:Edge Deletion 题意:给定一张n个顶点,m条边的带权无向图,已知从顶点1到各个顶点的最短路径为di,现要求保留最多k条边,使得从顶点1到各个顶点的最短距离为di的顶点最多.输出m ...
 - 【CF1076D】Edge Deletion 最短路+贪心
		
题目大意:给定 N 个点 M 条边的无向简单联通图,留下最多 K 条边,求剩下的点里面从 1 号顶点到其余各点最短路大小等于原先最短路大小的点最多怎么构造. 题解:我们可以在第一次跑 dij 时直接采 ...
 - Edge Deletion CodeForces - 1076D(水最短路)
		
题意: 设从1到每个点的最短距离为d,求删除几条边后仍然使1到每个点的距离为d,使得剩下的边最多为k 解析: 先求来一遍spfa,然后bfs遍历每条路,如果d[v] == d[u] + Node[i] ...
 - 1076D  Edge Deletion 【最短路】
		
题目:戳这里 题意:求出1到所有点的最短路径后,把边减到小于等于k条,问保留哪些边可以使仍存在的最短路径最多. 解题思路:这题就是考求最短路的原理.比如dijkstra,用优先队列优化后存在队列中的前 ...
 - 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 ...
 - Codeforces 437C  The Child and Toy(贪心)
		
题目连接:Codeforces 437C The Child and Toy 贪心,每条绳子都是须要割断的,那就先割断最大值相应的那部分周围的绳子. #include <iostream> ...
 - Codeforces Round #546 (Div. 2) D 贪心 + 思维
		
https://codeforces.com/contest/1136/problem/D 贪心 + 思维 题意 你面前有一个队列,加上你有n个人(n<=3e5),有m(m<=个交换法则, ...
 - Educational Codeforces Round 54 (Rated for Div. 2) D:Edge Deletion
		
题目链接:http://codeforces.com/contest/1076/problem/D 题意:给一个n个点,m条边的无向图.要求保留最多k条边,使得其他点到1点的最短路剩余最多. 思路:当 ...
 - Codeforces Round #303 (Div. 2)(CF545) E Paths and Trees(最短路+贪心)
		
题意 求一个生成树,使得任意点到源点的最短路等于原图中的最短路.再让这个生成树边权和最小. http://codeforces.com/contest/545/problem/E 思路 先Dijkst ...
 
随机推荐
- Struts2框架中使用Servlet的API示例
			
1. 在Action类中也可以获取到Servlet一些常用的API * 需求:提供JSP的表单页面的数据,在Action中使用Servlet的API接收到,然后保存到三个域对象中,最后再显示到JSP的 ...
 - Confluence 6 数据库问题解除
			
有关数据库相关的问题,请参考 Database Troubleshooting 中的内容. 希望获得更多的帮助,请参考 Troubleshooting Problems and Requesting ...
 - day10 函数2
			
为什么需要函数? 先使用目前的知识点实现一个需求: """ 三个功能 1.登录 2.购物车 3.收藏夹 收藏夹和 购物车 需要先登录才能使用! ...
 - python并发编程之IO模型,
			
了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调 ...
 - jmeter BeanShell实例-----两个变量之间的断言对比
			
jmeter BeanShell实例-----两个变量之间的断言对比 在jmeter的中,断言没法对两个变量的进行对比后判断,只能使用Bean Shell断言来进行,总是有人来问怎么写呢.这里写一个简 ...
 - jenkins上节点显示swap空间不足解决方案
			
查看内存占用情况:free -m 1.swap分区原理: swap分区在系统的物理内存不够用的时候,把物理内存中的一部分空间释放出来,以供当前运行的程序使用.那些被释放的空间可能来自一些很长时 ...
 - python编程实现十进制的转换(十进制到任何进制不用系统函数实现)
			
# 用户给定一个十进制数据,以及进制n, 完成n进制的转换,输出结果给用户(不要借助已有函数) # 用户的输入进制数据Decdata = int(input("请输入一个十进制数据:&quo ...
 - 005-Python字典
			
Python字典(dict) 字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号{}中: ...
 - 【C++ Primer 第13章】1.  拷贝控制、赋值和销毁
			
拷贝控制.赋值和销毁 如果一个构造函数的第一个参数是自身类的引用,且额外的参数都有默认值,则此构造函数是拷贝控制函数(拷贝构造函数不应该是explicit的). 如果我们没有为一个类定义拷贝构造函数, ...
 - 分库分表之后全局id怎么生成
			
数据库自增id: 这个就是说你的系统里每次得到一个id,都是往一个库的一个表里插入一条没什么业务含义的数据,然后获取一个数据库自增的一个id.拿到这个id之后再往对应的分库分表里去写入. 这个方案的好 ...