题目链接
题目大意
给你n个点,m条边,k次询问,每次输入x,询问你哪个点到x点的距离最远,
如果存在则输出这个最远的点的号,如果该x是孤立的则输出0
题解
样例
输入
7 5 4
1 2
2 3
3 1
4 5
5 6
1 4 5 7
输出
2
6
4
0
根据样例得到的图是这个样子的。
关于山1能喊到的最远距离,有人可能会觉得是2,有人可能会觉得是3,
- 觉得是3的人可能认为喊山的传递路径是 1->2->3
- 觉得是2的部分人可能认为喊山的传递路径是 1->3->2
然而都不对,根据题意喊山是按照最短距离来计算两座山的距离的,也就是1喊到2的距离就是1,而1喊到3的距离也是1,根据题目要求相同距离时候,选择编号小的山
既然考虑的距离是按最短距离算的,那么我就考虑到了最短路,每次的询问都是一个起始点,就dijkstra去跑一遍到这个起始点的所有距离,然后找最长距离即可。
- 优化后的迪杰斯塔拉应该和BFS跑的是差不多
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 11111;
vector<pair<int, int>> E[MAXN];
int n;
const int INF = 0x3f3f3f3f;
int dis[MAXN];
void dij(int s){
fill(dis, dis+MAXN, INF);
dis[s] = 0;
priority_queue<pair<int, int> > q;
q.push(make_pair(0, s));
while(!q.empty()){
pair<int, int> now = q.top();
q.pop();
if (now.first != dis[now.second]) continue;
for(pair<int,int> u : E[now.second]){
if (dis[u.first] > dis[now.second] + u.second){
dis[u.first] = dis[now.second] + u.second;
q.push(make_pair(dis[u.first], u.first));
}
}
}
bool judge = false;
bool fiind = true;
int ind;
for(int i = 1; i <= n; i++){
//cout << "i : " << i << " " << dis[i] << '\n';
if (dis[i] != INF) {
judge = true;
}
if (fiind && dis[i] != INF) ind = i, fiind = false;
if (dis[i] != INF && dis[i] > dis[ind]) ind = i;
}
if (judge == false || dis[ind] == 0) printf("0\n");
else printf("%d\n", ind);
}
int main(){
for(int i = 0; i < MAXN; i++) E[i].clear();
int m, k; cin >> n >> m >> k;
for(int i = 0; i < m; i++){
int a, b;
cin >> a >> b;
E[a].push_back(make_pair(b, 1));
E[b].push_back(make_pair(a, 1));
}
for(int i = 0; i < k; i++){
int x; cin >> x;
dij(x);
}
}