zoukankan      html  css  js  c++  java
  • [51nod1443]路径和树

      给定一幅无向带权连通图G = (V, E) (这里V是点集,E是边集)。从点u开始的最短路径树是这样一幅图G1 = (V, E1),其中E1是E的子集,并且在G1中,u到所有其它点的最短路径与他在G中是一样的。

      现在给定一幅无向带权连通图G和一个点u。你的任务是找出从u开始的最短路径树,并且这个树中所有边的权值之和要最小。

     Input
      第一行有两个整数n和m(1 ≤ n ≤ 3*10^5, 0 ≤ m ≤ 3*10^5),表示点和边的数目。
      接下来m行,每行包含3个整数 ui, vi, wi ,表示ui和vi之间有一条权值为wi的无向边(1 ≤ ui,vi ≤ n, 1 ≤ wi ≤ 10^9)。
      输入保证图是连通的。
      最后一行给出一个整数u (1 ≤ u ≤ n),表示起点。
     Output
      输出这棵树的最小的权值之和。

      不能直接求完最短路图后跑MST。。因为最短路图的边都是有向的。答案应该是最短路图里每个点最小的前驱边之和。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cmath>
     7 #define ll long long
     8 #define ui unsigned int
     9 #define ull unsigned long long
    10 using namespace std;
    11 const int maxn=300233;
    12 struct zs{int too,pre,dis;}e[maxn<<1];int tot,last[maxn];
    13 int dl[10023333],pre[maxn];
    14 ll dis[maxn],ans;
    15 int i,j,k,n,m;
    16 bool u[maxn];
    17 
    18 int ra,fh;char rx;
    19 inline int read(){
    20     rx=getchar(),ra=0,fh=1;
    21     while((rx<'0'||rx>'9')&&rx!='-')rx=getchar();
    22     if(rx=='-')fh=-1,rx=getchar();
    23     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh;
    24 }
    25 
    26 
    27 inline void insert(int a,int b,int c){
    28     e[++tot].too=b,e[tot].dis=c,e[tot].pre=last[a],last[a]=tot,
    29     e[++tot].too=a,e[tot].dis=c,e[tot].pre=last[b],last[b]=tot;
    30 }
    31 inline void spfa(int s){
    32     memset(dis+1,60,n<<3);
    33     int l=0,r=1,i,now,to;dl[1]=s,dis[s]=0;
    34     while(l<r)for(now=dl[++l],u[now]=0,i=last[now];i;i=e[i].pre)
    35     if(dis[to=e[i].too]>dis[now]+e[i].dis){
    36         dis[to]=dis[now]+e[i].dis,pre[to]=e[i].dis;
    37         if(!u[to])dl[++r]=to,u[to]=1;
    38     }else if(dis[to]==dis[now]+e[i].dis&&e[i].dis<pre[to])pre[to]=e[i].dis;
    39 }
    40 int main(){
    41     n=read(),m=read();
    42     for(i=1;i<=m;i++)j=read(),k=read(),insert(j,k,read());
    43     int s=read();spfa(s);
    44     for(i=1;i<=n;i++)ans+=pre[i];
    45     printf("%lld
    ",ans);
    46 }
    View Code
  • 相关阅读:
    Linux的学习--系统目录
    PHP内核的学习--创建PHP扩展
    PHP的学习--连接MySQL的三种方式
    MIME Type
    颜色的命名
    JavaScript的学习--生成二维码
    MySQL的学习--触发器
    Google Guava之--cache
    java代码调用oracle存储过程
    oracle序列
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5946664.html
Copyright © 2011-2022 走看看