[LCA && problem solution] Luo Gu 1967 trucking

Topic Portal

Topic Description : A
state-owned n cities, numbered from 1 to n, m there are two-way road between cities. Every road has a weight limit on vehicles, referred to as the weight limit. Q There are trucks in the transportation of goods, drivers want to know every car, without exceeding the weight limit of the vehicle, up to transport multiple goods.


Input Output Format
Input format:
The first line has a space separated by two integers n, m denotes n State A city roads and m.
The next three lines each m integers x, y, z between two integers each separated by a space, there is a weight limit represents the path from x to z to y number of urban city number. Note: x is not equal to y, may be a number of roads between the two cities.
The next line there is an integer q, q expressed need for freight trucks.
Next q lines of two integers x, y, between separated by a space, represents a need for a truck to transport goods from city x to y city, note: x is not equal to y.


Output Format:
A total of q lines, each an integer that represents for each truck, its maximum load is. If the truck can not reach the destination, output -1.


Analysis: Because the distance between two points is the minimum weight path, the maximum weight you want, then that is the smallest maximum, then we think the maximum spanning tree. We run the largest spanning tree re-built map, then run on the new map doubling LCA record weights and corresponding to his father.

We try to use f a [ i ] [ j ] four [c] [j] indicates the i-th point above 2 j 2^j What is the point of generation, and then m O [ i ] [ j ] I [i] [j] indicates the i-th point upward 2 j 2^j What (the smallest maximum) minimum weight generation is

We can launch the following formula:

f a [ i ] [ j ] = f a [ f a [ i ] [ j 1 ] ] [ j 1 ] four [c] [j] = four [four [c] [j-1]] [j-1]
m O [ i ] [ j ] = m i n ( m O [ i ] [ j 1 ] , m O [ f a [ i ] [ j 1 ] ] [ j 1 ] ) and [i] [j] = min (mo [i] [j-1], and [fa [i] [j-1] [j-1])

We just need a pre-run of these two formulas in the trees again doubling seeking to LCA

Then the specific code as follows:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int fa[100010][20];
int f[100010];
bool vis[100010];
int mo[100010][20];
struct node{
    int x,y,v;
}e1[1000010];
struct node1{
    int y,Next,v;
}e[1000100];
int cnt=0,len=0;
int linkk[100010];
int d[100010];
int d1[100010];
bool mycmp(node x,node y){
    return x.v>y.v;
}
int getfa(int k){
    return k==f[k]?k:f[k]=getfa(f[k]); 
}
void insert(int x,int y,int v){
    e[++len].Next=linkk[x];
    linkk[x]=len;
    e[len].y=y;
    e[len].v=v;
}
void dfs(int x,int de){
	if (vis[x]) return;
	vis[x]=1;
    d[x]=de;
    for (int i=linkk[x];i;i=e[i].Next){
	    int y=e[i].y;
	    if (y==fa[x][0]) continue;
	    fa[y][0]=x;
	    mo[y][0]=e[i].v;
	    dfs(y,de+1);
	}
}
void find_fa(){
    for (int j=1;j<=19;j++)
      for (int i=1;i<=n;i++)
         fa[i][j]=fa[fa[i][j-1]][j-1],mo[i][j]=min(mo[i][j-1],mo[fa[i][j-1]][j-1]);
}
int lca(int u,int v){
	if (getfa(u)!=getfa(v)) return -1;
	int ans=10000000;
    if (d[u]>d[v]) swap(u,v);
    for (int i=19;i>=0;i--)
      if (d[fa[v][i]]>=d[u]) ans=min(ans,mo[v][i]),v=fa[v][i];
    if (u==v) return ans;
    for (int i=19;i>=0;i--)
      if (fa[u][i]!=fa[v][i]) ans=min(ans,min(mo[u][i],mo[v][i])),u=fa[u][i],v=fa[v][i];
    return min(ans,min(mo[u][0],mo[v][0]));
}
int main(){
    scanf("%d %d",&n,&m);
    for (int i=1,x,y,z;i<=m;i++) scanf("%d %d %d",&x,&y,&z),e1[++cnt]=(node){x,y,z},e1[++cnt]=(node){y,x,z};
    sort(e1+1,e1+cnt+1,mycmp);
    for (int i=1;i<=n;i++) f[i]=i;
    for (int i=1;i<=cnt;i++){
	    int x=getfa(e1[i].x),y=getfa(e1[i].y);
	    if (x!=y)
	      f[x]=y,insert(x,y,e1[i].v),insert(y,x,e1[i].v);//最大生成树建边
	}
	int root=1;
    for (int i=1;i<=n;i++)
      if (!vis[i]){
      	  d[i]=1;
	      dfs(i,1);
	      fa[i][0]=i;
	      mo[i][0]=10000000;
	  }//可能是森林,搜索未搜索的点,并计算出深度 
	find_fa();//预处理出fa数组 
	int q;
	scanf("%d",&q);
	for (int i=1,x,y;i<=q;i++) scanf("%d %d",&x,&y),printf("%d\n",lca(x,y));//输出它们最近公共祖先的权值,此时即最小的最大载重 
}

Guess you like

Origin blog.csdn.net/huang_ke_hai/article/details/87334427