uva11354

来源:互联网 发布:js如何定义集合 编辑:程序博客网 时间:2024/05/18 19:44
#include<iostream>#include<cstdio>#include<algorithm>#include<vector>using namespace std;struct edgee{int from, to, cost;edgee(int from, int to, int cost) :from(from), to(to), cost(cost){}edgee(){}bool operator<( edgee b){return cost < b.cost;}};int edgetot;edgee edge[300000];vector<int>tree[100000];int dist[100000][25],fanum[100000][25];int dfn[100000],visit[100000];int n, m;void addedge(int from, int to, int cost){edge[edgetot] = edgee(from, to, cost);edgetot++;}int fa[100000];void init(){for (int i = 1; i <= n; i++)fa[i] = i;}int find(int x){return fa[x] == x ? x : fa[x] = find(fa[x]);}bool unionn(int x, int y){x = find(x);y = find(y);if (x == y)return false;elsefa[x] = y;return true;}void kruscal(){sort(edge, edge + edgetot);init();for (int i = 0; i < edgetot; i++){int from = edge[i].from,to = edge[i].to;if (unionn(from, to))tree[from].push_back(i), tree[to].push_back(i);}}void dfs(int num,int deep){dfn[num] = deep;//treestack.push_back(num);visit[num] = 1;for (int i = 0; i < tree[num].size(); i++){int edgenum = tree[num][i];int to = (edge[edgenum].from == num) ? edge[edgenum].to : edge[edgenum].from;if (visit[to] == 1)continue;int tempfa = num; dist[to][0] = edge[edgenum].cost; fanum[to][0] = tempfa;for (int j = 1; fanum[tempfa][j - 1] != -1; j++){fanum[to][j] = fanum[tempfa][j - 1]; dist[to][j] = max(dist[to][j - 1], dist[tempfa][j - 1]);tempfa = fanum[tempfa][j - 1];}dfs(to,deep+1);}}int lca(int x, int y){int ans = -1;if (dfn[x] < dfn[y])swap(x, y);int d = dfn[x] - dfn[y];for (int i = 0; d > 0; i++){if (d % 2)ans = max(ans, dist[x][i]), x = fanum[x][i]; d = d / 2;}for (int j = 20; j >= 0; j--){if (fanum[x][j] == fanum[y][j])continue;ans = max(ans, dist[x][j]); ans = max(ans, dist[y][j]);x = fanum[x][j], y = fanum[y][j];}if (x != y)ans = max(ans, dist[x][0]), ans = max(ans, dist[y][0]);return ans;}int main(){bool blank = false;while (scanf("%d%d", &n, &m) != EOF){edgetot = 0; if (blank) putchar(10);//这道题就是这个地方坑。。。每次输入前除了第一次都要输出一个空行putchar(10)=printf("\n");很迷的输入法。。    blank = true;for (int i = 0; i < m; i++)scanf("%d%d%d", &edge[i].from, &edge[i].to, &edge[i].cost), edgetot++;for (int i = 1; i <= n; i++){dfn[i] = 0; tree[i].clear(); visit[i] = 0;for (int j = 0; j <= 20; j++)fanum[i][j] = -1;}kruscal();dfs(1,0);//cout << "sdsdsdsd" << endl;int q;scanf("%d", &q);while (q--){//cout << "sdsds" << endl;int a, b;scanf("%d%d", &a, &b);int ans = lca(a, b);printf("%d\n", ans);}//printf("\n");}}

原创粉丝点击