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

Posted samhx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「日常训练」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); ++i)
#define per(i, a, b) for (repType i = (a); i >= (b); --i)
#define QUICKIO                      ios::sync_with_stdio(false);     cin.tie(0);                      cout.tie(0);
using namespace std;
using ll=long long;
using repType=int;

struct Edge
{
    int u, v;
    ll w;
    Edge() {}
    Edge(int _u, int _v, ll _w): u(_u), v(_v), w(_w) {}
    bool
    operator < (const Edge& rhs) const
    {
        if(w==rhs.w)
            { return (u==rhs.u)?v<rhs.v:u<rhs.u; }
        else { return w<rhs.w; }
    }
};

const int MAXN=300005;
vector<Edge> edges;
vector<int> G[MAXN];

void
add_edge(int u, int v, ll w)
{
    edges.PB(u, v, w);
    G[u].PB(int(edges.size())-1);
}

ll dist[MAXN];
int pre[MAXN]; // pre: last edge

void
dijkstra(int start)
{
    memset(pre, -1, sizeof(pre));
    memset(dist, 0x3f, sizeof(dist));
    using P=pair<ll, int>;
    priority_queue<P, vector<P>, greater<> > pq; // <dist, pnt>: 大根堆
    dist[start]=0;
    pq.push(MP(0, start));
    while(!pq.empty())
    {
        auto now=pq.top(); pq.pop();
        int u=now.se;
        if(dist[u]<now.fi) { continue; }
        rep(i, 0, int(G[u].size())-1)
        {
            int v=edges[G[u][i]].v;
            ll  w=edges[G[u][i]].w;
            if(dist[v]>dist[u]+w)
            {
                dist[v]=dist[u]+w;
                pre[v]=G[u][i];
                pq.push(MP(dist[v], v));
            }
            else if(dist[v]==dist[u]+w && edges[pre[v]].w>edges[G[u][i]].w)
                { pre[v]=G[u][i]; }
        }
    }
}

int
main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    rep(i, 1, m)
    {
        int u, v;
        ll w;
        scanf("%d%d%lld", &u, &v, &w);
        add_edge(u, v, w);
        add_edge(v, u, w);
    }

    int stp; scanf("%d", &stp);
    dijkstra(stp);

    ll ans=0;
    rep(i, 1, n) if(i!=stp) { ans+=edges[pre[i]].w; }
    printf("%lld
", ans);
    rep(i, 1, n) if(i!=stp) { printf("%d ", pre[i]/2+1); }
    printf("
");

    return 0;
}

以上是关于「日常训练」Paths and Trees(Codeforces Round 301 Div.2 E)的主要内容,如果未能解决你的问题,请参考以下文章

转:Monoids and Finger Trees

1-Trees and Queries

Expression Trees (C# and Visual Basic)

E. 1-Trees and Queries

Random Forest And Extra Trees

数据结构篇四:Binary Trees and Binary Search Trees (BST)