如果我们只建立一个超级源点,这个点连接所有感兴趣的点的能一步直接到达的点,连接的边权大小与这些感兴趣的点和该点的边权大小相同,然后跑一遍dijskla,得到的对全图的最短路中在感兴趣的点中dis最小的 举个例子,样例的第二个中超级源点连接:点5边权10,点4边权2,点7边权3,点2边权6 这样感觉没什么问题,但写出的程序40分,并且题解里没有 Code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,int> pli;
const int N=1e5+10;
const ll inf = 0x3f3f3f3f3f3f3f3f;
int n,m,k,T,lk[N];
vector<pii> G[N];
priority_queue<pli,vector<pli>,greater<pli> > pq;
bool vis[N];
ll dis[N];
void dijskla(){
for(int i=1;i<=k;i++){
for(auto v:G[lk[i]]){
int x = v.second;
dis[x] = min(dis[x],v.first*1ll);
pq.push({v.first,v.second});
//printf("len %lld to %d has been pushed.\n",v.first*1ll,v.second);
}
}
//cout<<"\n"<<"\n";
pli cur,nxt;
while(!pq.empty()){
cur = pq.top();
//printf("len %lld to %d has been carried.\n",cur.first,cur.second);
pq.pop();
if(cur.first > dis[cur.second]){
//printf("It's continued.\n");
continue;
}
vis[cur.second] = true;
for(auto v:G[cur.second]){
if(vis[v.second]) continue;
int x = v.second;
if(dis[x] > dis[cur.second]+v.first){
dis[x] = dis[cur.second]+v.first;
pq.push({dis[x],x});
//printf("len %lld to %d has been pushed.\n",dis[x],x);
}
}
}
}
signed main(){
cin>>T;
while(T--){
cin>>n>>m>>k;
for(int i=1;i<=n;i++) G[i].clear();
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
G[u].push_back({w,v});
}
memset(dis,inf,sizeof(dis));
memset(vis,false,sizeof(vis));
for(int i=1;i<=k;i++) cin>>lk[i];
dijskla();
ll ans = inf;
for(int i=1;i<=k;i++) ans = min(ans,dis[lk[i]]);
cout<<ans<<"\n";
}
return 0;
}
重要声明:这不是题解,因为Code没AC