545E. Paths and Trees

题目链接

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

思路:先求一遍最短路,从所有到i点的满足最短路的边中选一条权最小的边。

Java程序

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;

public class E545 {
    private static class Edge {
        int v;
        long w;
        int index;

        Edge(int v, long w, int index) {
            this.v = v;
            this.w = w;
            this.index = index;
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        PrintStream out = System.out;

        int n = in.nextInt(), m = in.nextInt();
        List<Edge>[] graph = new List[n];

        for (int i = 0; i < n; i++) {
            graph[i] = new ArrayList<E545.Edge>();
        }

        for (int i = 1; i <= m; i++) {
            int v1 = in.nextInt() - 1;
            int v2 = in.nextInt() - 1;
            long w = in.nextLong();

            graph[v1].add(new Edge(v2, w, i));
            graph[v2].add(new Edge(v1, w, i));
        }
        int u = in.nextInt() - 1;

        Edge[] lastEdge = new Edge[n];
        final long[] min = new long[n];
        for (int i = 0; i < n; i++) {
            min[i] = -1;
        }

        min[u] = 0;
        Queue<Integer> q = new LinkedList<Integer>();

        q.add(u);

        while (!q.isEmpty()) {
            int v = q.poll();

            for (Edge edge : graph[v]) {
                int v1 = edge.v;
                long min1 = min[v] + edge.w;

                if ((min[v1] == -1) || (min1 < min[v1])
                        || (min1 == min[v1] && edge.w < lastEdge[v1].w)) {

                    min[v1] = min1;
                    lastEdge[v1] = edge;
                    q.add(v1);
                }
            }
        }

        long res = 0;
        boolean[] f = new boolean[m];

        for (int i = 0; i < n; i++) {
            if (lastEdge[i] != null) {
                res += lastEdge[i].w;
                f[lastEdge[i].index - 1] = true;
            }
        }

        out.println(res);

        StringBuilder s = new StringBuilder();
        boolean first = true;
        for (int i = 0; i < m; i++) {
            if (f[i]) {
                if (!first) {
                    s.append(" ");
                }
                s.append(i + 1);
                first = false;
            }
        }
        out.println(s.toString());
        in.close();
        out.close();

    }

}

 

Python代码

import heapq as hq

class edge(object):
    def __init__(self, to, w, nr):
        self.to = to
        self.w = w
        self.nr = nr

n, m = map(int, raw_input().split())
adj = [[] for _ in range(n + 1)]
for i in range(1, m+1):
    u, v, c = map(int, raw_input().split())
    adj[u].append((v, c, i))
    adj[v].append((u, c, i))
root = int(raw_input())
vis = [False] * (n+1)
q = [(0, 0, root, 0)]
ans = []
tot = 0
while q:
    d, c, n, e = hq.heappop(q)
    if vis[n]:
        continue
    ans.append(e)
    tot += c
    vis[n] = True
    for v, c, i in adj[n]:
        if not vis[v]:
            hq.heappush(q, (d+c, c, v, i))
ans = map(str, ans)
print tot
print " ".join(ans[1:])

 

上面的代码都是在codeforces上面抄过来的,自己写不出来。。。。

时间: 2024-11-13 10:52:12

545E. Paths and Trees的相关文章

CF 545E Paths and Trees

题目大意:给出n个点,m条无向边,每条边有长度.求一棵树,要求树上的每个点到源点距离最小的前提下,使得树上的边的长度和最小.输出树上边的总长度,以及树上的边的序号(按输入顺序 1...m). 思路 :单源最短路径 + 贪心 .用Dijkstra 或spfa 算法 求每个点到源点的最短路径,并在记录当前用来更新每个点最短距离的那条边(即pre[i]记录点i所对应的变).  若当前这条边能使得某个点到源点的距离变小则更新该点到源点的距离,并记录更新该点的边; 若当前这条边更新某节点后,使得该点到源点

Codeforces Round #303 (Div. 2) E. Paths and Trees (最短路+变形最小生成树)

题目地址:E. Paths and Trees 模拟了一场CF,这场实在太水了..边玩边做的..最后半分钟交了一发E题..不幸AK绝杀失败.... 首先的思路肯定是先求最短路,把可能为最短路的边挑出来,然后第二步我本来写的是直接用无向图的最小生成树,于是绝杀失败...后来才发现这样是不行的..因为边是有向边,而且每个点的入度要保证只有一个才行.于是我就把最小生成树的边弄成有向边,然后判定一下每个点的入度保证为1.然后就过了.. 代码如下: #include <iostream> #includ

「日常训练」Paths and Trees(Codeforces Round 301 Div.2 E)

题意与分析 代码 #include <bits/stdc++.h> #define MP make_pair #define PB emplace_back #define fi first #define se second #define ZERO(x) memset((x), 0, sizeof(x)) #define ALL(x) (x).begin(),(x).end() #define rep(i, a, b) for (repType i = (a); i <= (b);

Codeforce 水题报告(2)

又水了一发Codeforce ,这次继续发发题解顺便给自己PKUSC攒攒人品吧 CodeForces 438C:The Child and Polygon: 描述:给出一个多边形,求三角剖分的方案数(n<=200). 首先很明显可能是区间dp,我们可以记f[i][j]为从i到j的这个多边形的三角剖分数,那么f[i][j]=f[i][k]*f[j][k]*(i,j,k是否为1个合格的三角形) CodeForces 438D:The Child and Sequence 描述:给一个序列,要求支持区

topic model - LDA 1

http://blog.csdn.net/pipisorry/article/details/42129099 step1 :install gensim step 2 :Corpora and Vector Spaces 将用字符串表示的文档转换为用id表示的文档向量: documents = ["Human machine interface for lab abc computer applications", "A survey of user opinion of

文本相似性计算

文本相似性计算三个阶段: 1. 字面的匹配相似 2. 词汇的匹配相似 3. 语义的匹配相似 一.JaccardSimilarity方法 对文本进行分词,然后对每一个单词分配一个唯一的ID(token),为了计算文本之间的相似性.JaccardSimilarity方法的计算方法是: 两个集合的交集/两个集合的并集二.文本的向量化 文本->向量化为向量->向量空间中的某一个点->求两个点(即两个文本)之间的距离->得到文档的相似性 2.1 简单的向量化 为每一个词语分配一个唯一的ID,

uva 122 trees on the level——yhx

题目如下:Given a sequence of binary trees, you are to write a program that prints a level-order traversal of each tree. In this problem each node of a binary tree contains a positive integer and all binary trees have have fewer than 256 nodes. In a level

Trees on the level

Background Trees are fundamental in many branches of computer science. Current state-of-the art parallel computers such as Thinking Machines' CM-5 are based on fat trees. Quad- and octal-trees are fundamental to many algorithms in computer graphics.

Behavior trees for AI: How they work

http://www.gamasutra.com/blogs/ChrisSimpson/20140717/221339/Behavior_trees_for_AI_How_they_work.php by Chris Simpson on 07/17/14 09:35:00 pm       27 comments       The following blog post, unless otherwise noted, was written by a member of Gamasutra