货车运输

 

所以需要建立树,记录从特定起点到某处的限重的最大值,最大生成树

//kruskal可以保证树的生成是严格按照从大到小,保证答案的正确性

 

查询:xy之间的lca

 

没了

 

#include<bits/stdc++.h>
const int INF=19270817;
using namespace std;
int n,m,head[10005],q,tail,fa[10005][25],f[10005],dep[10005],maxn[10005][25];
struct edge
{
    int x,y,v,nex;
}e[100005];
edge b[100005];
void read(int &p)
{
    p=0;
    int flag=1;
    char s=getchar();
    while(!isdigit(s))
    {
        if(s=='-') flag=-1;
        s=getchar();
    }
    for(;isdigit(s);s=getchar()) p=p*10+s-'0';
    p*=flag;
}

void add(int x,int y,int v)
{
    e[++tail].x=x;
    e[tail].y=y;
    e[tail].v=v;
}

void add_edge(int x,int y,int v)
{
    b[++tail].x=x;
    b[tail].y=y;
    b[tail].v=v;
    b[tail].nex=head[x];
    head[x]=tail;
 } 
 
int getfa(int x)
{
    if(f[x]==x) return f[x];
    return f[x]=getfa(f[x]);
 } 

bool cmp(edge a,edge k)
{
    return a.v>k.v;
}
//这是什么阴间使用方法?我怕不是个憨憨


void kruskal()
{
    tail=0;
    int cnt=0;
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=m;i++)
    {
        int f1=getfa(e[i].x),f2=getfa(e[i].y);
        if(f1!=f2)
        {
            f[f1]=f2;
            add_edge(e[i].x,e[i].y,e[i].v);
            add_edge(e[i].y,e[i].x,e[i].v);
            cnt++;
        }
        if(cnt==n-1) return ;
    }
}

void dfs(int x)
{
    for(int i=head[x];i;i=b[i].nex)
    {
        int y=b[i].y;
        if(!dep[y])
        {
            dep[y]=dep[x]+1;
            fa[y][0]=x;
            maxn[y][0]=b[i].v;
            dfs(y);
        }
    }
}

void first_deal()
{
    for(int i=1;i<=n;i++)
    if(!dep[i]) 
    {
        dep[i]=1;
        fa[i][0]=0;
        dfs(i);
    }
    
    for(int k=1;k<=20;k++)
    for(int i=1;i<=n;i++)
    {
        fa[i][k]=fa[fa[i][k-1]][k-1];
        maxn[i][k]=min(maxn[i][k-1],maxn[fa[i][k-1]][k-1]);
    }
}

int ask(int x,int y)
{
    if(getfa(x)!=getfa(y)) return -1;
    if(dep[x]<dep[y]) swap(x,y);
    int ans=INF;
    for(int i=20;i>=0;i--)
    {
        if(dep[fa[x][i]]>=dep[y])
        {
            ans=min(ans,maxn[x][i]);
            x=fa[x][i];
        }
    }
    if(x==y) return ans;
    for(int i=20;i>=0;i--)
    {
        if(fa[x][i]!=fa[y][i])
        {
            ans=min(ans,min(maxn[x][i],maxn[y][i]));
            x=fa[x][i];y=fa[y][i];
        }
    }
    ans=min(ans,min(maxn[x][0],maxn[y][0]));
    return ans;
}

int main()
{
    read(n);read(m);
    int x,y,v;
    for(int i=1;i<=m;i++)
    {
        read(x);read(y);read(v);
        add(x,y,v);
    }
    sort(e+1,e+m+1,cmp);
//注意这里的排序
    kruskal();
    //for(int i=1;i<=n;i++) f[i]=i; 
    first_deal();
//预处理……

    read(q);
    for(int i=1;i<=q;i++)
    {
        read(x);read(y);
        printf("%d\n",ask(x,y));
    }
    return 0;
 } 

 

#include<bits/stdc++.h>

const int INF=19270817;

using namespace std;

int n,m,head[10005],q,tail,fa[10005][25],f[10005],dep[10005],maxn[10005][25];

struct edge

{

int x,y,v,nex;

}e[100005];

edge b[100005];

void read(int &p)

{

p=0;

int flag=1;

char s=getchar();

while(!isdigit(s))

{

if(s=='-') flag=-1;

s=getchar();

}

for(;isdigit(s);s=getchar()) p=p*10+s-'0';

p*=flag;

}

 

void add(int x,int y,int v)

{

e[++tail].x=x;

e[tail].y=y;

e[tail].v=v;

}

 

void add_edge(int x,int y,int v)

{

b[++tail].x=x;

b[tail].y=y;

b[tail].v=v;

b[tail].nex=head[x];

head[x]=tail;

 } 

 

int getfa(int x)

{

if(f[x]==x) return f[x];

return f[x]=getfa(f[x]);

 } 

 

bool cmp(edge a,edge k)

{

return a.v>k.v;

}

//这是什么阴间使用方法?我怕不是个憨憨

 

 

void kruskal()

{

tail=0;

int cnt=0;

for(int i=1;i<=n;i++) f[i]=i;

for(int i=1;i<=m;i++)

{

int f1=getfa(e[i].x),f2=getfa(e[i].y);

if(f1!=f2)

{

f[f1]=f2;

add_edge(e[i].x,e[i].y,e[i].v);

add_edge(e[i].y,e[i].x,e[i].v);

cnt++;

}

if(cnt==n-1) return ;

}

}

 

void dfs(int x)

{

for(int i=head[x];i;i=b[i].nex)

{

int y=b[i].y;

if(!dep[y])

{

dep[y]=dep[x]+1;

fa[y][0]=x;

maxn[y][0]=b[i].v;

dfs(y);

}

}

}

 

void first_deal()

{

for(int i=1;i<=n;i++)

if(!dep[i]

{

dep[i]=1;

fa[i][0]=0;

dfs(i);

}

 

for(int k=1;k<=20;k++)

for(int i=1;i<=n;i++)

{

fa[i][k]=fa[fa[i][k-1]][k-1];

maxn[i][k]=min(maxn[i][k-1],maxn[fa[i][k-1]][k-1]);

}

}

 

int ask(int x,int y)

{

if(getfa(x)!=getfa(y)) return -1;

if(dep[x]<dep[y]) swap(x,y);

int ans=INF;

for(int i=20;i>=0;i--)

{

if(dep[fa[x][i]]>=dep[y])

{

ans=min(ans,maxn[x][i]);

x=fa[x][i];

}

}

if(x==y) return ans;

for(int i=20;i>=0;i--)

{

if(fa[x][i]!=fa[y][i])

{

ans=min(ans,min(maxn[x][i],maxn[y][i]));

x=fa[x][i];y=fa[y][i];

}

}

ans=min(ans,min(maxn[x][0],maxn[y][0]));

return ans;

}

 

int main()

{

read(n);read(m);

int x,y,v;

for(int i=1;i<=m;i++)

{

read(x);read(y);read(v);

add(x,y,v);

}

sort(e+1,e+m+1,cmp);

//注意这里的排序

kruskal();

//for(int i=1;i<=n;i++) f[i]=i; 

first_deal();

//预处理……

 

read(q);

for(int i=1;i<=q;i++)

{

read(x);read(y);

printf("%d\n",ask(x,y));

}

return 0;

 }

posted @ 2021-03-02 16:29  Adaxy  阅读(31)  评论(0编辑  收藏  举报