• 51nod 1443 路径和树(最短路树)


    题目链接:路径和树

    题意:给定无向带权连通图,求从u开始边权和最小的最短路树,输出最小边权和。

    题解:构造出最短路树,把存留下来的边权全部加起来。(跑dijkstra的时候松弛加上$ < $变成$ <= $,因为之后跑到该顶点说明是传递下来的,该情况边权和最小。)

    以样例作说明:第一次从顶点3跑到顶点1,最短路为2;第二次从顶点3经过顶点2跑到顶点1,最短路也为2,但是第二次跑的方式可以把从顶点3跑到顶点2的包括进去,这样形成的最短路树边权和最小。

     1 #include <queue>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 typedef long long ll;
     9 const int N=3e5+10;
    10 
    11 struct qnode{
    12     ll v,w;
    13     qnode(){}
    14     qnode(ll v,ll w):v(v),w(w){}
    15     bool operator < (const qnode& b) const{
    16         return w>b.w;
    17     }
    18 };
    19 
    20 struct node{
    21     ll nxt,v,w;
    22     node(){}
    23     node(ll nxt,ll v,ll w):nxt(nxt),v(v),w(w){}
    24 };
    25 
    26 ll n,m,tot,ans=0;
    27 node edge[N<<1];
    28 ll head[N],d[N],w[N];
    29 qnode cur,tmp;
    30 bool vis[N];
    31 priority_queue <qnode> Q;
    32 pair <ll,ll> fa[N];
    33 vector <ll> g[N];
    34 
    35 void add_edge(ll u,ll v,ll w){
    36     edge[tot]=node(head[u],v,w);
    37     head[u]=tot++;
    38 }
    39 
    40 void init(){
    41     tot=1;
    42     memset(head,0,sizeof(head));
    43 }
    44 
    45 void dijkstra(ll s){
    46     memset(vis,0,sizeof(vis));
    47     for(int i=0;i<N;i++) d[i]=1e18;
    48     d[s]=0;
    49     Q.push(qnode(s,0));
    50     while(!Q.empty()){
    51         cur=Q.top();
    52         Q.pop();
    53         ll u=cur.v;
    54         if(vis[u]) continue;
    55         vis[u]=true;
    56         for(ll i=head[u];i;i=edge[i].nxt){
    57             ll v=edge[i].v;
    58             ll w=edge[i].w;
    59             if(d[u]+w<=d[v]){
    60                 d[v]=d[u]+w;
    61                 fa[v]=make_pair(u,(i+1)/2);
    62                 Q.push(qnode(v,d[v]));
    63             }
    64         }
    65     }
    66 }
    67 
    68 void dfs(ll u,ll father){
    69     for(ll v:g[u]){
    70         if(v!=father) dfs(v,u);
    71     }
    72     ans+=w[fa[u].second];
    73 }
    74 
    75 int main(){
    76     init();
    77     scanf("%lld%lld",&n,&m);
    78     for(int i=1;i<=m;i++){
    79         ll u,v;
    80         scanf("%lld%lld%lld",&u,&v,&w[i]);
    81         add_edge(u,v,w[i]);
    82         add_edge(v,u,w[i]);
    83     }
    84     ll st;
    85     scanf("%lld",&st);
    86     dijkstra(st);
    87     for(ll i=1;i<=n;i++){
    88         if(st==i) continue;
    89         g[fa[i].first].push_back(i);
    90     }
    91     dfs(st,0);
    92     printf("%lld
    ",ans);
    93     return 0;
    94 }
    View Code
  • 相关阅读:
    Android 动画
    Eclipse设置软tab(用4个空格字符代替)及默认utf-8文件编码(unix)
    android ANR
    Android 服务端开发之开发环境配置
    安装Android sdk 4.4(19)出现问题的解决方案
    adb uninstall/pull/push 命令的使用总结
    Android学习笔记1 android adb启动失败问题 adb server is out of date. killing...
    Android.mk文件语法规范 原文
    Android MediaProvider数据库模式
    Android MVC模式
  • 原文地址:https://www.cnblogs.com/pavtlly/p/9959968.html
Copyright © 2020-2023  润新知