Codeforces 545E. Paths and Trees[最短路+贪心]
[题目大意]
题目将从某点出发的所有最短路方案中,选择边权和最小的最短路方案,称为最短生成树。
题目要求一颗最短生成树,输出总边权和与选取边的编号。
[题意分析]
比如下面的数据:
5 5
1 2 2
2 3 2
3 4 16
1 5 18
4 5 2
1
这个图对于从 1 出发,有两种最短路。
这种最短路方案中 dis[2]=2,dis[3]=4,dis[4]=20,dis[5]=18。边权总和 Sum=44
但如果这样选边,1点到各点的距离依然为最短路,但Sum降为了24。
那么如何选择到最优的方案呢。 由于最短路方案构成的图一定是一棵树,所以我们可以将 除源点外 的所有顶点搞一个贪心。
改写dijkstra算法(c[]数组用来存取与该点连接的边的cost,s[]数组用来存取与该点连接的边的编号):
const ll inf=0x7fffffffffffff;
struct Edge{
int to,cost,id;
Edge(int T,int C,int D):to(T),cost(C),id(D){}
};
typedef pair<long long,int> P;
vector<Edge>G[];
ll d[],c[];
void dij(int u){
fill(d,d+n+,inf);
fill(c,c+n+,inf);
d[u]=;
priority_queue<P,vector<P>,greater<P>> q;
q.push(P(d[u],u));
while(!q.empty()){
P p=q.top();
q.pop();
int v=p.second;
if(d[v]<p.first) continue;
for(int i=;i<G[v].size();i++){
Edge e=G[v][i];
if(d[e.to]>d[v]+e.cost){
d[e.to]=d[v]+e.cost;
s[e.to]=e.id;
c[e.to]=e.cost;
q.push(P(d[e.to],e.to));
}
else if(d[e.to]==d[v]+e.cost&&c[e.to]>e.cost){
s[e.to]=e.id;
c[e.to]=e.cost;
}
}
}
}
当有多条路通往一个顶点,且这两种路线cost相同时,我们可以将 通往该顶点的边 和 该顶点 绑定起来,我们希望每个顶点都能绑定合法的(不影响最短路的)且权值最小的边。
在dijkstra算法中我们每次挑选优先队列中权值最小的路。当碰上两条路cost相等的时候,我们选择与下一个点连接且边权最小的那一条边与下一个点绑定(Cost[nextV]=e.cost)。
* 由于最短路中从源点通往每个点的路可以组成一颗树 且 点只与从源点走向该点的边相绑定,所以一个点 一定可以 绑定一条边。
选取完毕后,我们只需要遍历 c[] 数组求出总花费,再遍历 s[] 数组输出每个点绑定的边的编号即可。
***Code:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int m,n,s[];
const ll inf=0x7fffffffffffff;
struct Edge{
int to,cost,id;
Edge(int T,int C,int D):to(T),cost(C),id(D){}
};
typedef pair<long long,int> P;
vector<Edge>G[];
ll d[],c[];
void dij(int u){
fill(d,d+n+,inf);
fill(c,c+n+,inf);
d[u]=;
priority_queue<P,vector<P>,greater<P>> q;
q.push(P(d[u],u));
while(!q.empty()){
P p=q.top();
q.pop();
int v=p.second;
if(d[v]<p.first) continue;
for(int i=;i<G[v].size();i++){
Edge e=G[v][i];
if(d[e.to]>d[v]+e.cost){
d[e.to]=d[v]+e.cost;
s[e.to]=e.id;
c[e.to]=e.cost;
q.push(P(d[e.to],e.to));
}
else if(d[e.to]==d[v]+e.cost&&c[e.to]>e.cost){
s[e.to]=e.id;
c[e.to]=e.cost;
}
}
}
}
int main(){
int u,v,co;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
scanf("%d%d%d",&u,&v,&co);
G[u].push_back(Edge(v,co,i));
G[v].push_back(Edge(u,co,i));
}
scanf("%d",&u);
dij(u);
ll sum=;
for(int i=;i<=n;i++){
if(i!=u) sum+=c[i];
}
cout<<sum<<endl;
for(int i=;i<=n;i++){
if(i!=u) cout<<s[i]<<' ';
}
return ;
}
2017/7/13
Codeforces 545E. Paths and Trees[最短路+贪心]的更多相关文章
- Codeforces 545E. Paths and Trees 最短路
E. Paths and Trees time limit per test: 3 seconds memory limit per test: 256 megabytes input: standa ...
- 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 545E] Paths and Trees
[题目链接] https://codeforces.com/contest/545/problem/E [算法] 首先求 u 到所有结点的最短路 记录每个节点最短路径上的最后一条边 答 ...
- 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 input standard ...
- 545E. Paths and Trees
题目链接 题意:给定一个无向图和一个点u,找出若干条边组成一个子图,要求这个子图中u到其他个点的最短距离与在原图中的相等,并且要求子图所有边的权重之和最小,求出最小值并输出子图的边号. 思路:先求一遍 ...
- Codeforces 1076D Edge Deletion 【最短路+贪心】
<题目链接> 题目大意: n个点,m条边的无向图,现在需要删除一些边,使得剩下的边数不能超过K条.1点为起点,如果1到 i 点的最短距离与删除边之前的最短距离相同,则称 i 为 " ...
- CF 545E Paths and Trees
题目大意:给出n个点,m条无向边,每条边有长度.求一棵树,要求树上的每个点到源点距离最小的前提下,使得树上的边的长度和最小.输出树上边的总长度,以及树上的边的序号(按输入顺序 1...m). 思路 : ...
- codeforces 545E E. Paths and Trees(单源最短路+总权重最小)
E. Paths and Trees time limit per test:3 seconds memory limit per test:256 megabytes input:standard ...
- Codeforces Round #303 (Div. 2) E. Paths and Trees Dijkstra堆优化+贪心(!!!)
E. Paths and Trees time limit per test 3 seconds memory limit per test 256 megabytes input standard ...
随机推荐
- 快速排序的一种Java实现
快速排序是笔试和面试中很常见的一个考点.快速排序是冒泡排序的升级版,时间复杂度比冒泡排序要小得多.除此之外,快速排序是不稳定的,冒泡排序是稳定的. 1.原理 (1)在数据集之中,选择一个元素作为&qu ...
- 安装 Azure CLI
首先安装node 和 npm 的安装 官方推荐v4.4.4长期支持版 1.下载并解压 node-v4.4.4-linux-x64.tar.xz tar -xJf node-v4.4.4-linux-x ...
- npm install -g cnpm --registry=https://registry.npm.taobao.org
npm install -g cnpm --registry=https://registry.npm.taobao.org
- org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'userId' not found. Available parameters are [arg1, arg0, param1, param2]
2018-06-27 16:43:45.552 INFO 16932 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : ...
- 粗谈Android未来前景
Andriod作为智能手机机兴起的操作系统,有着非同寻常的地位.而相对于他的竞争对手ios,两大系统各有自身的优缺点,有太多的不同点,但相比较用户体验来说ios略胜一筹. Android系统极具开发性 ...
- Luogu P4593 [TJOI2018]教科书般的亵渎
亵渎终于离开标准了,然而铺场快攻也变少了 给一个大力枚举(无任何性质)+艹出自然数幂和的方法,但是复杂度极限是\(O(k^4)\)的,不过跑的好快233 首先简单数学分析可以得出\(k=m+1\),因 ...
- CPP-基础:String类
已知类String的原型为: class String { public: String(const char *str = NULL); // 普通构造函数 String(const String ...
- 八 个优秀的 jQuery Mobile 教程
jQuery Mobile 是 jQuery 在手机上和平板设备上的版本.jQuery Mobile不仅会给主流移动平台带来jQuery核心库,而且会发布一个完整统一的jQuery移动UI框架.虽然j ...
- 实现类似AOP的封装和配置
这是张孝祥老师Java进阶讲解中最后一个视频,就是实现类似spring中的AOP的封装和配置,特别特别小型的一个框架雏形,但是spring中的核心思想还是体现出来了,真的厉害,张老师!!! 一.重点知 ...
- MongoDB在java中的使用
在一年前就开始在项目中使用Mongodb作为爬虫(crawler)待下载URL.下载成功URL等的存储库,最近对项目进行版本更新,根据Mongodb的最近升级情况,也对项目中的Mongodb进行了相关 ...