1 条题解
-
0

// 最短路+二进制分组 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
信息
- ID
- 4010
- 时间
- 5000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 3
- 上传者