/*author:2486memory:0 kbtime:2222 mslanguage:c++11 4.8.2result:acceptedvj runid:4236841real runid:15859210*/#includ E <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue># Include <vector>using namespace std;const int maxn=50000+5;const int maxm=100000+5;int n,m,m;int par[maxn],dist[ Maxn],depth[maxn],vis[maxn];struct Edge {int u,v,cost; BOOL operator< (const edge &a) Const {return cost<a.cost; }} es[maxm];struct ed {int to,cost; Ed (int to,int cost): To, cost (cost) {}};vector<ed>g[maxn];void init (int. c) {for (int i=0; i<maxn; i++) { Par[i]=i; Dist[i]=-1; if (c) g[i].clear (); } memset (Vis,false,sizeof (Vis));} int find (int x) {return par[x]==x?x:par[x]=find (par[x]);} BOOL Same (int x,int y) {return find (x) ==find (y);} void Unite (int x,int y) {x=find (x); Y=find (y); Par[x]=y;} int LCA (int a, int b) {//a depth <=b depth int m1 =-1; while (dEpth[a] < Depth[b]) {//The depth is tuned to the same M1 = MAX (M1, Dist[b]); b = Par[b]; while (A! = b) {//GO from node to ancestor node M1 = MAX (M1, Dist[a]); M1 = MAX (M1, Dist[b]); A = Par[a], B = par[b]; } return M1;} void kj () {sort (es,es+m); Init (1); int cnt=0; /********** the edges that make up the smallest spanning tree are all saved *************//********** Everyone knows, this is the Kruskal algorithm *************/for (int i=0; i<m; i++) { Edge E=es[i]; if (!same (E.V,E.U)) {unite (E.V,E.U); G[e.v].push_back (Ed (e.u,e.cost)); G[e.u].push_back (Ed (e.v,e.cost)); }}/***********************/dist[1]=0; depth[1]=0; queue<int>f; F.push (1); Vis[1]=true; Init (0); /********* this is important. **************//********* takes the city of 1th as the root node and then begins to traverse the formation of a tree **************//*********** you can imagine, If the city ************/on one of the nodes of a tree/*********** then what is the path from one point to another? //*********** It is very simple to push them up from their own node up to the common ancestor of two points ************//*********** is the path from one point to another ******//*********** So, directly with the queue processing can ************/while (! F.empty ()) {int V=f.front (); F.pop (); for (int i=0; i<g[v].size (); i++) {ed e=g[v][i]; if (vis[e.to]) continue; Vis[e.to]=true; par[e.to]=v;//His father node depth[e.to]=depth[v]+1;//his depth dist[e.to]=e.cost;//from that node to the risk of the Father node F.pu SH (e.to); }}/***********************/}int Main () {int Cases=1;//freopen ("D://imput.txt", "R", stdin); while (~SCANF ("%d%d", &n,&m)) {for (int i=0; i<m; i++) {scanf ("%d%d%d", &es[i].u,&es[i] . v,&es[i].cost); } if (cases!=1) printf ("\ n");//Pay attention to the problem format, need to line KJ (); int s,t; scanf ("%d", &m); while (m--) {scanf ("%d%d", &s,&t);//Read command if (Depth[s]>depth[t]) swap (s,t); printf ("%d\n", LCA (S,t)); } cases++; } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Uva-11354bond minimum spanning tree, LCA looking for recent public ancestor