题目大意:给出n个点,m条无向边,每条边有长度。求一棵树,要求树上的每个点到源点距离最小的前提下,使得树上的边的长度和最小。输出树上边的总长度,以及树上的边的序号(按输入顺序 1...m).

思路 :单源最短路径 + 贪心 .用Dijkstra 或spfa 算法 求每个点到源点的最短路径,并在记录当前用来更新每个点最短距离的那条边(即pre[i]记录点i所对应的变)。

    若当前这条边能使得某个点到源点的距离变小则更新该点到源点的距离,并记录更新该点的边; 若当前这条边更新某节点后,使得该点到源点的距离不变(即:d[e[t].to] = d[e[t].from] + e[t].length ) 则比较这条边与当前该点所记录的边的长度大小,若这条边比改点所记录的边长度要小(即e[pre[e[t].to]].length > e[t].length),则更新改点所记录的边(pre[e[t].to] = t)。

代码 :

  1. #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<stdlib.h>
    #include<queue>
    #define INF 0x7fffffffffffffff
    #define pii pair<long long,long long>
    using namespace std;
    long long s,n,m,pre[300002],tag[600002],u[600002],v[600002],next[600002],first[300002];
    long long sum,d[300002],w[600002];
    priority_queue<pii,vector<pii>,greater<pii> > Q;
    bool vis[300002]; void input(){
    long long i,j,a,b,c;
    for(i=1;i<=n;i++)
    first[i] = -1;
    for(i=1;i<=m;i++){
    scanf("%I64d %I64d %I64d",&u[i],&v[i],&w[i]);
    u[i+m] = v[i] ;
    v[i+m] = u[i] ;
    w[i+m] = w[i] ;
    next[i] = first[u[i]];
    first[u[i]] = i ;
    next[i+m] = first[v[i]];
    first[v[i]] = i+m ;
    }
    scanf("%I64d",&s);
    } void Dijkstra(){
    long long i,j;
    memset(vis,0,sizeof(vis));
    memset(tag,0,sizeof(tag));
    for(i=1;i<=n;i++)
    pre[i] = -1 ;
    for(i=1;i<=n;i++)
    d[i] = INF;
    d[s] = 0;
    Q.push(make_pair(d[s],s));
    while(!Q.empty()){
    pii t = Q.top();
    Q.pop();
    long long x = t.second;
    if(vis[x])
    continue;
    vis[x] = true;
    for(long long e=first[x]; e!=-1; e=next[e]){
    if(d[v[e]] > d[x] + w[e] && d[x] < INF){
    pre[v[e]] = e;
    d[v[e]] = d[x] + w[e] ;
    Q.push(make_pair(d[v[e]],v[e]));}elseif(d[v[e]]== d[x]+ w[e]&& d[x]< INF && w[pre[v[e]]]> w[e]){
    pre[v[e]]= e;
    Q.push(make_pair(d[v[e]],v[e]));}}}}int main(){longlong i,j;while(scanf("%I64d%I64d",&n,&m)==2){
    input();
    sum =0;Dijkstra();for(i=1;i<=n;i++){
    sum += w[pre[i]];
    tag[pre[i]]=1;} printf("%I64d\n",sum);longlong count =0;for(i=1;i<=2*m;i++)if(tag[i]){if(i > m){if(count !=0)
    printf(" %I64d",i-m);else
    printf("%I64d",i-m);}elseif(i<=m){if(count !=0)
    printf(" %I64d",i);else
    printf("%I64d",i);}
    count ++;}
    printf("\n");}return0;}

CF 545E Paths and Trees的更多相关文章

  1. Codeforces 545E. Paths and Trees 最短路

    E. Paths and Trees time limit per test: 3 seconds memory limit per test: 256 megabytes input: standa ...

  2. 545E. Paths and Trees

    题目链接 题意:给定一个无向图和一个点u,找出若干条边组成一个子图,要求这个子图中u到其他个点的最短距离与在原图中的相等,并且要求子图所有边的权重之和最小,求出最小值并输出子图的边号. 思路:先求一遍 ...

  3. Codeforces 545E. Paths and Trees[最短路+贪心]

    [题目大意] 题目将从某点出发的所有最短路方案中,选择边权和最小的最短路方案,称为最短生成树. 题目要求一颗最短生成树,输出总边权和与选取边的编号.[题意分析] 比如下面的数据: 5 5 1 2 2 ...

  4. [Codeforces 545E] Paths and Trees

    [题目链接] https://codeforces.com/contest/545/problem/E [算法] 首先求 u 到所有结点的最短路 记录每个节点最短路径上的最后一条边         答 ...

  5. codeforces 545E E. Paths and Trees(单源最短路+总权重最小)

    E. Paths and Trees time limit per test:3 seconds memory limit per test:256 megabytes input:standard ...

  6. 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 ...

  7. 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 ...

  8. 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 ...

  9. Codeforces Paths and Trees

    Paths and Trees time limit per test3 seconds memory limit per test256 megabytes Little girl Susie ac ...

随机推荐

  1. Windows下编译eXosip、osip,以及UAC和UAS的例子

    今天开始了SIP开源库的学习,我选择了osip和eXosip,但是这两个库的编译使用有些麻烦,源码下来之后编译会出现很多问题,网上也没有找到完整的编译介绍,只能一步一步的找办法解决,最后终于编译成功! ...

  2. poj2429:因数分解+搜索

    题意:给定gcd(a,b)和lcm(a,b) 求使得a+b最小的 a,b 思路:结合算数基本定理中 gcd lcm的质因子表示形式 把lcm(a,b)质因数分解 以后 通过dfs找到 a+b最小的a ...

  3. spoj1812-Longest Common Substring II(后缀自动机)

    Description A string is finite sequence of characters over a non-empty finite set Σ. In this problem ...

  4. map循环遍历删除

    typedef map<string,int> MapFileList; int main() { MapFileList m_SingleList; m_SingleList.inser ...

  5. WPF多线程问题

    最近碰到这种多线程问题都是在WPF项目中. 1. 问题是这样.有个一主界面线程,然后background线程启动,这个background线程试图去修改主界面里面的数据. 造成死锁. 调用过程,主界面 ...

  6. 第18讲- UI常用组件之EditText

    第18讲UI常用组件之EditText 三.文本输入框EditText EditTex类继承自TextView.EditText是接受用户输入信息的最重要控件.在html当中,相当于<input ...

  7. c++ 11 多线程教学(1)

    本篇教学代码可在GitHub获得:https://github.com/sol-prog/threads. 在之前的教学中,我展示了一些最新进的C++11语言内容: 1. 正则表达式(http://s ...

  8. (转)vivoxshot 精英版三模转五模模式切换操作方法

    https://yunpan.cn/cPUBWc8vtKpID (提取码:de92) 本帖最后由 韩爱峰 于 2016-3-29 23:00 编辑 碰到不少机友在使用过程中操作不成功,现将我的方法跟大 ...

  9. EF中执行原生sql与使用Local获取本地数据

    使用DbSet的Local属性可以访问当前context中被追踪且没有被标记为删除的实体(内存中的数据) using (var context = new BloggingContext()) { / ...

  10. VS2010 ReportViewer导出文件下载保存不能识别文件类型

    今天测试项目时,突然发现导出报表下载保存的保存,不能识别文件的类型,文件名称为:.xls[3] 检查代码发现在指定报表路径时多了一个方法: ReportViewer1.LocalReport.Load ...