[51NOD1443]路径和树:最短路+最小树形图

分析:

先用Heap_Dijkstra()求一遍u到所有点的单源最短路。
然后对于有向边i如果有dis[begin[i]]+length[i]==dis[end[i]],那么这条有向边i就是最短路上的边。
将所有这样的边找出来跑朱刘算法求一遍最小树形图即可。
因为只包含最短路边的图肯定是一张DAG,所以求最小树形图的算法会好写很多。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <queue>
typedef long long LL;

inline int read(){
    int x=0;char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x;
}

const int MAXN=3e5+5;
const int MAXM=3e5+5;
int n,m,s,ecnt,head[MAXN];
LL dis[MAXN],len[MAXN],ans;
bool vis[MAXN];
struct Edge{
    int to,nxt;
    LL w;
}e[MAXM<<1];
struct Pair{
    int pos;
    LL dis;
    friend bool operator > (Pair x,Pair y){
        return x.dis>y.dis;
    }
};
std::priority_queue<Pair,std::vector<Pair>,std::greater<Pair> > q;

inline void add_edge(int bg,int ed,int val){
    ecnt++;
    e[ecnt].to=ed;
    e[ecnt].nxt=head[bg];
    e[ecnt].w=val;
    head[bg]=ecnt;
}

inline void dijkstra(){
    memset(dis,0x3f,sizeof dis);
    while(!q.empty()) q.pop();
    dis[s]=1;
    q.push((Pair){s,0});
    while(!q.empty()){
        int u=q.top().pos;q.pop();
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=head[u];i;i=e[i].nxt){
            int ver=e[i].to;
            if(dis[ver]>dis[u]+e[i].w){
                dis[ver]=dis[u]+e[i].w;
                q.push((Pair){ver,dis[ver]});
            }
        }
    }
}

inline void zhuliu(){
    memset(len,0x3f,sizeof len);
    for(int i=1;i<=n;i++)
        for(int j=head[i];j;j=e[j].nxt){
            int ver=e[j].to;
            if(dis[ver]==dis[i]+e[j].w)
                len[ver]=std::min(len[ver],e[j].w);
        }
    for(int i=1;i<=n;i++)
        if(i!=s) ans+=len[i];
}

int main(){
    n=read(),m=read();
    for(int i=1;i<=m;i++){
        int u=read(),v=read(),w=read();
        add_edge(u,v,w);
        add_edge(v,u,w);
    }
    s=read();
    dijkstra();
    zhuliu();
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ErkkiErkko/p/9699986.html