1 条题解

  • 0
    @ 2026-6-18 15:35:10

    // 最短路+二进制分组 Dijkstra 算法 O(40*MlogN)
    #include<bits/stdc++.h>
    #define ll long long
    #define pli pair<ll,int>
    using namespace std;
    
    int read(){
      int x=0,f=1;char c=getchar();
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) x=10*x+c-'0';
      return x*f;
    }
    const int N=1e5+5,M=5e5+5;
    int h[N],to[M],ww[M],ne[M],idx;
    void add(int a,int b,int c){
      to[++idx]=b,ww[idx]=c,ne[idx]=h[a],h[a]=idx;
    }
    int T,n,m,k,q[N];
    ll d[N]; bool vis[N];
    vector<int> A,B;
    
    ll dijkstra(vector<int> s,vector<int> t){
      memset(vis,0,sizeof vis);
      for(int i=1;i<=n;i++) d[i]=1e18;
      priority_queue<pli,vector<pli>,greater<pli>> q;
      for(int i=0;i<s.size();i++) q.push({0,s[i]}),d[s[i]]=0;
      
      while(!q.empty()){
        int u=q.top().second; q.pop();
        if(vis[u]) continue; vis[u]=1;
        for(int i=h[u];i;i=ne[i]){
          int v=to[i],w=ww[i];
          if(d[v]>d[u]+w){
            d[v]=d[u]+w;
            q.push({d[v],v});
          }
        }
      }
      ll mi=1e18;
      for(int i=0;i<t.size();i++) mi=min(mi,d[t[i]]);
      return mi;
    }
    int main(){
      for(T=read();T--;){
        idx=0; memset(h,0,sizeof h);
        n=read(),m=read(),k=read();
        for(int i=1,a,b,c;i<=m;i++)a=read(),b=read(),c=read(),add(a,b,c);
        for(int i=1;i<=k;i++)q[i]=read();
    
        ll ans=1e18;
        for(int i=0;i<20;i++){
          A.clear(),B.clear();
          for(int j=1;j<=k;j++)
            if(q[j]>>i&1) A.push_back(q[j]); //第i位是1 分到A集合
            else B.push_back(q[j]);          //第i位是0 分到B集合
          ans=min(ans,min(dijkstra(A,B),dijkstra(B,A)));
        }
        printf("%lld\n",ans);
      }
    }
    
    • 1

    D91 最短路+二进制分组 Dijkstra 算法「GXOI / GZOI2019」旅行者

    信息

    ID
    4010
    时间
    5000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    3
    已通过
    3
    上传者