70pts求调qwq
查看原帖
70pts求调qwq
747882
_adil_楼主2024/7/19 07:49
#include<bits/stdc++.h>
#define N 100009
#define M 500009
#define INF 0x3f3f3f3f3f3f3f3f
#define mod 998244353
#define int long long
using namespace std;
typedef long double ldb;
typedef pair<int,int> pii;
int n,m,t,k,num1,num2,ans;
int vis[N],dis1[N],dis2[N],fr[N],to[N],p[N];
int head1[M],to1[M],val1[M],nxt1[M];
int head2[M],to2[M],val2[M],nxt2[M];
void clr(){
  num1=0,num2=0,ans=INF;
  memset(head1,0,sizeof(head1));memset(nxt1,0,sizeof(nxt1));
  memset(head2,0,sizeof(head2));memset(nxt2,0,sizeof(nxt2));
}
void add1(int u,int v,int w){
  to1[++num1]=v,nxt1[num1]=head1[u],head1[u]=num1,val1[num1]=w;
}
void add2(int u,int v,int w){
  to2[++num2]=v,nxt2[num2]=head2[u],head2[u]=num2,val2[num2]=w;
}
void dij1(){//正向,求特殊点到u
  for(int i=1;i<=n;i++)dis1[i]=INF,fr[i]=-1,vis[i]=0;
  priority_queue<pii,vector<pii>,greater<pii> > q;
  for(int i=1;i<=k;i++){
    dis1[p[i]]=0;q.push({0,p[i]});fr[p[i]]=p[i];//fr[x]是去到x最近的特殊点
  }
  while(!q.empty()){
    int u=q.top().second,tmpw=q.top().first;q.pop();
    if(vis[u])continue;vis[u]=1;
    for(int i=head1[u];i;i=nxt1[i]){
      int v=to1[i],w=val1[i];
      if(dis1[v]>dis1[u]+w){
        dis1[v]=dis1[u]+w;
        fr[v]=u;
        if(!vis[v])q.push({dis1[v],v});
      }
    }
  }
}
void dij2(){//反向,求u到特殊点
  for(int i=1;i<=n;i++)dis2[i]=INF,to[i]=-1,vis[i]=0;
  priority_queue<pii,vector<pii>,greater<pii> > q;
  for(int i=1;i<=k;i++){
    dis2[p[i]]=0;q.push({0,p[i]});to[p[i]]=p[i];//to[x]是x出发最近的特殊点
  }
  while(!q.empty()){
    int u=q.top().second,tmpw=q.top().first;q.pop();
    if(vis[u])continue;vis[u]=1;
    for(int i=head2[u];i;i=nxt2[i]){
      int v=to2[i],w=val2[i];
      if(dis2[v]>dis2[u]+w){
        dis2[v]=dis2[u]+w;
        to[v]=u;
        q.push({dis2[v],v});
      }
    }
  }
}
signed main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin>>t;
  while(t--){
    clr();
    cin>>n>>m>>k;
    for(int i=1;i<=m;i++){
      int u,v,w;
      cin>>u>>v>>w;
      if(u==v)continue;
      add1(u,v,w);add2(v,u,w);
    }
    for(int i=1;i<=k;i++)cin>>p[i];
    dij1();
    dij2();
    for(int u=1;u<=n;u++){
      for(int i=head1[u];i;i=nxt1[i]){
        int v=to1[i];
        if(fr[u]!=to[v])ans=min(ans,dis1[u]+dis2[v]+val1[i]);
      }
    }
    cout<<ans<<"\n";
  }
  return 0;
}
2024/7/19 07:49
加载中...