社区讨论

请问,倍增15分,每个WA都只错了2-3个查询,什么情况?

P1967[NOIP 2013 提高组] 货车运输参与者 4已保存回复 6

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
6 条
当前快照
1 份
快照标识符
@mi6mextj
此快照首次捕获于
2025/11/20 07:15
4 个月前
此快照最后确认于
2025/11/20 07:15
4 个月前
查看原帖
CPP
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,q;
int maxn,ans;
struct edge{
    int u,v,w,pre;
}e1[100005],e2[100005];
int last[20001],en=0;
void add(int u,int v,int w,edge e[])
{
    en++;
    e[en].u=u;
    e[en].v=v;
    e[en].w=w;
    e[en].pre=last[u];
    last[u]=en;
}
bool comp(const edge &a,const edge &b)
{
    return a.w>b.w;
}
int fa[20001];
int ff(int x)
{
    if(fa[x]!=x) return fa[x]=ff(fa[x]);
    return x;
}
void uni(int x,int y)
{
    int fx=ff(x);
    int fy=ff(y);
    if(fx!=fy) fa[fx]=fy;
}
void MST()
{
    memset(last,0,sizeof(last));
    en=0;
    int t=n-1;
    sort(e1+1,e1+1+m,comp);
    for(int i=1;i<=m;i++)
    {
        if(ff(e1[i].u)!=ff(e1[i].v))
        {
            add(e1[i].v,e1[i].u,e1[i].w,e2);
            add(e1[i].u,e1[i].v,e1[i].w,e2);
            uni(e1[i].u,e1[i].v);
            t--;
        }
        if(t==0) break;
    }
}
int dep[10001],anc[10001][20],dis[10001][20];
void dfs(int x,int f,int w)
{
    dep[x]=dep[f]+1;
    anc[x][0]=f;
    dis[x][0]=w;
    for(int i=1;i<=19;i++)
    {
        anc[x][i]=anc[anc[x][i-1]][i-1];
        dis[x][i]=min(dis[anc[x][i-1]][i-1],dis[x][i-1]);
    }
    for(int i=last[x];i!=0;i=e2[i].pre)
    {
        //if(!use[i]) continue;
         int to=e2[i].v;
        if(to!=f) 
        {
            dfs(to,x,e2[i].w);            
        }    
    }
}
int lca(int x,int y)
{
    if(ff(x)!=ff(y)) return 0;
    ans=maxn;
    if(dep[x]>dep[y]) swap(x,y);
    for(int i=0;i<=19;i++)
    {
        if((dep[y]-dep[x])>>i&1) 
        {
            ans=min(ans,dis[y][i]);
            y=anc[y][i];    
        }
    }
    for(int i=19;i>=0;i--)
    {
        if(anc[x][i]!=anc[y][i])
        {
            ans=min(ans,min(dis[x][i],dis[y][i]));
            x=anc[x][i];
            y=anc[y][i];
        }
    }
    ans=min(ans,min(dis[x][0],dis[y][0]));
    return anc[x][0]==anc[y][0];
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        cin>>x>>y>>z;
        fa[x]=x;fa[y]=y;
        add(x,y,z,e1);
    }
    MST();
    memset(dis,127,sizeof(dis));
    maxn=dis[1][1];
    dfs(1,1,maxn);
    cin>>q;
    for(int i=1;i<=q;i++)
    {
        int x,y;
        cin>>x>>y;
        if(lca(x,y)) cout<<ans<<"\n";
        else cout<<-1<<"\n";
    }
}

回复

6 条回复,欢迎继续交流。

正在加载回复...