【cogs1439】货车运输 生成树+lca

AC通道:http://cogs.pro/cogs/problem/problem.php?pid=1439

【题解】

首先取图的最大生成树建成一棵树,然后问题就转化为了求两点到lca路径上的最小边权,用倍增处理。

#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define INF 1000000000
#define MAXM 50010
#define MAXN 10010
struct node{int x,y,v;}E[MAXM];
struct node2{int y,next,v;}e[MAXN*2];
int n,m,q,len,vis[MAXN],f[MAXN],Link[MAXN],deep[MAXN],anc[MAXN][25],w[MAXN][25];
inline int read()
{
    int x=0,f=1;  char ch=getchar();
    while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
    while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
    return x*f;
}
bool cmp(node a,node b) {return a.v>b.v;} 
int find(int x)  {return f[x]==x?x:f[x]=find(f[x]);}
void insert(int x,int y,int v) {e[++len].next=Link[x];Link[x]=len;e[len].y=y;e[len].v=v;}
void dfs(int x)
{
    vis[x]=1;
    for(int i=1;i<=20;i++)  {anc[x][i]=anc[anc[x][i-1]][i-1]; w[x][i]=min(w[x][i-1],w[anc[x][i-1]][i-1]);}
    for(int i=Link[x];i;i=e[i].next)
        if(!vis[e[i].y])
        {
            deep[e[i].y]=deep[x]+1;
            anc[e[i].y][0]=x;
            w[e[i].y][0]=e[i].v;
            dfs(e[i].y);
        }
}
int lca(int x,int y)
{
    if(deep[x]=0;i--)  if(deep[anc[x][i]]>=deep[y])  x=anc[x][i];
    if(x==y)  return x;
    for(int i=20;i>=0;i--)  if(anc[x][i]!=anc[y][i])  x=anc[x][i],y=anc[y][i];
    return anc[x][0];
}
int ask(int x,int f)
{
    int mn=INF;
    int t=deep[x]-deep[f];
    for(int i=0;i<=16;i++)if(t&(1<


你可能感兴趣的:(【cogs1439】货车运输 生成树+lca)