输入第一行: n,m,Q 表示点的个数与边的个数和问题个数
接下来 m行:点a,点b,和它们的距离c
最后q行:询问点a与点b的最近公共祖先和距离
#include<iostream> #include<vector> #include<map> using namespace std; int dis[10010]; int vis[10010]; vector<int> maps[10010]; int querry[10010][10010]; int value[10010][10010]; int n, m, Q; int F[10011]; void join(int a,int b) { F[a] = b; } int find(int a) { while (a != F[a]) { a = F[a]; } return a; } void TarjanLCA(int root ,int weight) { int next; dis[root] = weight; vis[root] = 1; for (int i = 0; i < maps[root].size(); i++) { next = maps[root][i]; if (vis[maps[root][i]] == 0) { TarjanLCA(next, weight + value[root][next]); join(next, root); } } for (int i = 1; i <= n; i++) { if (querry[root][i] == 1 && vis[i] == 1) { querry[i][root] = 0; querry[root][i] = 0; cout << "from " << root << " to " << i << endl; cout << find(i) << endl; //输出最近公共祖先 cout << dis[root] + dis[i] - 2 * dis[find(i)] << endl;//输出两点之间的距离 } } } int main() { int i, j, k; int a, b, c; while (cin >> n>>m>>Q) { memset(querry, 0, sizeof(querry)); for (i = 1; i <= n; i++) F[i] = i; for (i = 1; i <= m; i++) { cin >> a >> b >> c; maps[a].push_back(b); value[a][b] = c; } for (i = 1; i <= Q; i++) { cin >> a >> b; querry[a][b] = 1; querry[b][a] = 1; } TarjanLCA(1, 0); } return 0; }
用 Tarjan找最近公共祖先,找最短路
最新推荐文章于 2022-10-27 20:33:26 发布