首页 > 其他 > 详细

【LOJ3087】「GXOI / GZOI2019」旅行者

时间:2019-04-21 22:07:07      阅读:143      评论:0      收藏:0      [点我收藏+]

题意

给定一个 \(n\) 个点 \(m\) 条边的的有向图,给出 \(k\) 个关键点,求关键点两两最短路的最小值。

\(n\le 10^5, m\le 5\cdot 10^5\).

Solution

二进制枚举。对于每一位,将编号当前位为 \(0\) 的点做源点, 当前位为 \(1\) 的点做汇点,然后跑最短路。

复杂度 \(O(n\log ^2 n)\) .

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
namespace io {
    const int SIZE=(1<<21)+1;
    char ibuf[SIZE],*iS,*iT,c; int qr;
#define gc()(iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
    inline int gi (){
        int x=0;
        for(c=gc();c<'0'||c>'9';c=gc());
        for(;c<='9'&&c>='0';c=gc()) x=(x<<1)+(x<<3)+(c&15); return x;
    }
} using io::gi;
const int N=1e5+5,M=5e5+5;
typedef long long ll;
int head[N],nxt[M],to[M],wei[M],n,m,k,key[N];
#define pr pair<int,int>
priority_queue< pr,vector<pr>,greater<pr> > q; 
ll dis[N];
void addedge(int u, int v, int w, int now) {
    nxt[now]=head[u], head[u]=now, to[now]=v, wei[now]=w;
}
int main()
{
#ifdef lc
    freopen("a.in","r",stdin);
#endif
    int T=gi();
    while(T--)
    {
        memset(head,0,sizeof(head));
        n=gi(),m=gi(),k=gi();
        for(int i=1;i<=m;++i)
        {
            int u=gi(),v=gi(),w=gi();
            addedge(u,v,w,i);
        }
        for(int i=1;i<=k;++i) key[i]=gi();
        ll ans=1ll<<60;
        for(int i=0;i<17;++i)
        {
            memset(dis,0x3f,sizeof(dis));
            for(int j=1;j<=k;++j)
                if(key[j]&(1<<i))
                {
                    dis[key[j]]=0;
                    q.push(make_pair(0,key[j]));
                }
            while(!q.empty())
            {
                ll tmp=q.top().first;
                int u=q.top().second; q.pop();
                if(dis[u]!=tmp)continue;
                for(int e=head[u];e;e=nxt[e])
                    if(dis[to[e]]>dis[u]+wei[e])
                    {
                        dis[to[e]]=dis[u]+wei[e];
                        q.push(make_pair(dis[to[e]],to[e]));
                    }
            }
            for(int j=1;j<=k;++j) if(!(key[j]&(1<<i))) ans=min(ans,dis[key[j]]); 
        }
        for(int i=0;i<17;++i)
        {
            memset(dis,0x3f,sizeof(dis));
            for(int j=1;j<=k;++j)
                if(!(key[j]&(1<<i)))
                {
                    dis[key[j]]=0;
                    q.push(make_pair(0,key[j]));
                }
            while(!q.empty())
            {
                ll tmp=q.top().first;
                int u=q.top().second; q.pop();
                if(dis[u]!=tmp)continue;
                for(int e=head[u];e;e=nxt[e])
                    if(dis[to[e]]>dis[u]+wei[e])
                    {
                        dis[to[e]]=dis[u]+wei[e];
                        q.push(make_pair(dis[to[e]],to[e]));
                    }
            }
            for(int j=1;j<=k;++j) if(key[j]&(1<<i)) ans=min(ans,dis[key[j]]); 
        }
        printf("%lld\n",ans);
    }
}

【LOJ3087】「GXOI / GZOI2019」旅行者

原文:https://www.cnblogs.com/farway17/p/10747216.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!