• [GX/GZOI2019]旅行者(dijkstra)


    二进制分组SB做法没意思还难写还可能会被卡常其实是我不会写。用一种比较优秀的O(Tnlogn)做法,只需要做2次dijkstra。对原图做一次、对反图做一次,然后记录每个点的最短路是从k个源点中的哪个转移过来的。然后枚举每条边,若两边转移过来的源点不同,则用d1+w[i]+d2来更新答案即可。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e5+7,M=5e5+7;
    struct node{int u;ll d;};
    bool operator<(node a,node b){return a.d>b.d;}
    int n,m,k,tot,a[N],vis[N],hd[N],v[M],nxt[M],w[M],st[M],ed[M],len[M],c[2][N];
    ll ans,d[2][N];
    void adde(int x,int y,int z){v[++tot]=y,nxt[tot]=hd[x],w[tot]=z,hd[x]=tot;}
    void dijkstra(ll*d,int*c)
    {
        priority_queue<node>q;
        for(int i=1;i<=n;i++)d[i]=1e18,vis[i]=0;
        for(int i=1;i<=k;i++)d[a[i]]=0,c[a[i]]=a[i],q.push((node){a[i],0});
        while(!q.empty())
        {
            int u=q.top().u;q.pop();
            if(vis[u])continue;
            vis[u]=1;
            for(int i=hd[u];i;i=nxt[i])
            if(d[v[i]]>d[u]+w[i])d[v[i]]=d[u]+w[i],c[v[i]]=c[u],q.push((node){v[i],d[v[i]]});
        }
    }
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n,&m,&k);
            for(int i=1;i<=n;i++)hd[i]=0;tot=0;
            for(int i=1,x,y,z;i<=m;i++)
            {
                scanf("%d%d%d",&x,&y,&z);
                if(x==y)i--,m--;
                else adde(x,y,z),st[i]=x,ed[i]=y,len[i]=z;
            }
            for(int i=1;i<=k;i++)scanf("%d",&a[i]);
            dijkstra(d[0],c[0]);
            for(int i=1;i<=n;i++)hd[i]=0;tot=0;
            for(int i=1;i<=m;i++)adde(ed[i],st[i],len[i]);
            dijkstra(d[1],c[1]);
            ans=1e18;
            for(int i=1;i<=m;i++)
            if(c[0][st[i]]&&c[1][ed[i]]&&c[0][st[i]]!=c[1][ed[i]])
            ans=min(ans,d[0][st[i]]+d[1][ed[i]]+len[i]);
            printf("%lld
    ",ans);
        }
    }
    View Code
  • 相关阅读:
    Android中layout_gravity和gravity的区别
    Android基础面试题
    小白学习设计模式之工厂模式
    装饰者模式视频示例
    小白学习设计模式之装饰者模式
    利用poi来向execl中写入对象
    java利用poi来读取execl表格返回对象
    java小白设计模式之观察者模式
    小白学习java设计模式之策略模式
    如何理解java是一个面向对象的语言?(转自Hollis的直面java)
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/10859263.html
Copyright © 2020-2023  润新知