版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/C_13579/article/details/81981327
地址:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2005
思路:求点到维修点的最短距离,若对于每一个询问都扫一遍那么就太费时,因此可以先将维修点到各点的最短距离求出来,利用Dijkstra算法将所有维修点当做起点处理,而对于各点最短距离的维修点的保存则可以用bitset来存储。
Code :
#include<iostream>
#include<algorithm>
#include<vector>
#include<bitset>
#include<queue>
using namespace std;
struct node{
int v;
int w;
bool operator<(const node &p)const{
return w>p.w;
}
};
const int INF=1e9;
const int MAX_N=10005;
const int MAX_S=1005;
int n,m,s,Q;
vector<node> e[MAX_N];
vector<int> d;
int dis[MAX_N];
bitset<MAX_S> a[MAX_N];
void Dijkstra();
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&s,&Q)){
for(int i=0;i<=n;++i)
e[i].clear(),a[i].reset();
d.clear();
int u,v,w;
for(int i=0;i<m;++i)
{
scanf("%d%d%d",&u,&v,&w);
e[u].push_back({v,w});
e[v].push_back({u,w});
}
for(int i=0;i<s;++i)
{
scanf("%d",&u);
d.push_back(u);
}
sort(d.begin(),d.end());
Dijkstra();
while(Q--){
scanf("%d",&u);
int p=0;
for(int i=0;i<=s;++i)
if(a[u][i]){
if(p) printf(" ");
p=1;
printf("%d",d[i]);
}
printf("\n");
}
}
return 0;
}
void Dijkstra()
{
for(int i=1;i<=n;++i)
dis[i]=INF;
priority_queue<node> Q;
for(int i=0;i<s;++i)
{
Q.push({d[i],0}); dis[d[i]]=0; a[d[i]][i]=1;
}
while(!Q.empty()){
int u=Q.top().v,w=Q.top().w; Q.pop();
if(w>dis[u]) continue;
for(auto t:e[u])
{
if(dis[t.v]>dis[u]+t.w){
dis[t.v]=dis[u]+t.w;
a[t.v]=a[u];
Q.push({t.v,dis[t.v]});
}else if(dis[t.v]==dis[u]+t.w)
a[t.v]|=a[u];
}
}
}