社区讨论

关于根节点

P1505[国家集训队] 旅游参与者 2已保存回复 5

讨论操作

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

当前回复
5 条
当前快照
1 份
快照标识符
@lo9cwftn
此快照首次捕获于
2023/10/28 09:21
2 年前
此快照最后确认于
2023/10/28 09:21
2 年前
查看原帖
题目上是连通图,那么不应该以任意一点为根节点dfs做线段树都是没问题的嘛?
这是AC代码R68816709
CPP
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>

#define inf 0x3f3f3f3f
#define ls (id<<1)
#define rs (id<<1|1)
#define mid ((l+r)>>1)

using namespace std;
const int maxn=2e5+5;

struct Segment_Tree{
    int maxd,mind,sum;
    bool lazy;
}tr[maxn<<2];
int n,m;
struct Edge{
    int v,w,next;
}e[maxn<<1];
int p[maxn],len;
int dfn[maxn],timestamp;
int top[maxn];
int siz[maxn],depth[maxn];
int son[maxn],fa[maxn];
int w[maxn],v[maxn];

void add(int u,int v,int w){
    e[len]=(Edge){v,w,p[u]},p[u]=len++;
}

void pushup(int id){
    tr[id].sum=tr[ls].sum+tr[rs].sum;
    tr[id].maxd=max(tr[ls].maxd,tr[rs].maxd);
    tr[id].mind=min(tr[ls].mind,tr[rs].mind);
}

void pushdown(int id){
    if (tr[id].lazy){
        tr[ls].lazy^=1;
        tr[rs].lazy^=1;
        tr[ls].sum*=-1,tr[rs].sum*=-1;
        tr[ls].maxd*=-1,tr[ls].mind*=-1,swap(tr[ls].maxd,tr[ls].mind);
        tr[rs].maxd*=-1,tr[rs].mind*=-1,swap(tr[rs].maxd,tr[rs].mind);
        tr[id].lazy=false;
    }
}

void build(int id,int l,int r){
    if (l==r){
        tr[id].sum=tr[id].maxd=tr[id].mind=w[l];
        return;
    }
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(id);
}

void change(int id,int l,int r,int x,int v){//把这个数改掉
    if (l==r){
        tr[id].sum=tr[id].maxd=tr[id].mind=v;
        return;
    }
    pushdown(id);
    if (x<=mid) change(ls,l,mid,x,v);
    else change(rs,mid+1,r,x,v);
    pushup(id);
}

void update(int id,int l,int r,int a,int b){//变成相反数
    if (a<=l&&r<=b){
        tr[id].lazy^=1;
        tr[id].sum*=-1;
        tr[id].maxd*=-1,tr[id].mind*=-1;
        swap(tr[id].maxd,tr[id].mind);
        return;
    }
    pushdown(id);
    if (a<=mid) update(ls,l,mid,a,b);
    if (b>mid) update(rs,mid+1,r,a,b);
    pushup(id);
}

int query_sum(int id,int l,int r,int a,int b){//SUM
    if (a<=l&&r<=b){
        return tr[id].sum;
    }
    int res=0;
    pushdown(id);
    if (a<=mid) res+=query_sum(ls,l,mid,a,b);
    if (b>mid) res+=query_sum(rs,mid+1,r,a,b);
    return res;
}

int query_max(int id,int l,int r,int a,int b){
    if (a<=l&&r<=b){
        return tr[id].maxd;
    }
    int res=-inf;
    pushdown(id);
    if (a<=mid) res=max(res,query_max(ls,l,mid,a,b));
    if (b>mid) res=max(res,query_max(rs,mid+1,r,a,b));
    return res;
}

int query_min(int id,int l,int r,int a,int b){
    if (a<=l&&r<=b){
        return tr[id].mind;
    }
    int res=inf;
    pushdown(id);
    if (a<=mid) res=min(res,query_min(ls,l,mid,a,b));
    if (b>mid) res=min(res,query_min(rs,mid+1,r,a,b));
    return res;
}

void dfs1(int u,int f){
    fa[u]=f;
    depth[u]=depth[f]+1;
    siz[u]=1;
    int maxsize=-1;
    for (int i=p[u];~i;i=e[i].next){
        int vi=e[i].v,wi=e[i].w;
        if (vi==f) continue;
        v[vi]=wi;
        dfs1(vi,u);
        siz[u]+=siz[vi];
        if (maxsize<siz[vi]){
            maxsize=siz[vi];
            son[u]=vi;
        }
    }
}

void dfs2(int u,int t){
    dfn[u]=++timestamp;
    top[u]=t;
    w[timestamp]=v[u];
    if (!son[u]) return;
    dfs2(son[u],t);
    for (int i=p[u];~i;i=e[i].next){
        int v=e[i].v;
        if (v==fa[u]||v==son[u]) continue;
        dfs2(v,v);
    }
}

/* 注意!边权变成点权,不能算lca的权值 */
int qsum(int x,int y){
    int res=0;
    while (top[x]!=top[y]){
        if (depth[top[x]]<depth[top[y]]){
            swap(x,y);
        }
        res+=query_sum(1,1,n,dfn[top[x]],dfn[x]);
        x=fa[top[x]];
    }
    if (depth[x]>depth[y]) swap(x,y);
    if (x!=y) res+=query_sum(1,1,n,dfn[x]+1,dfn[y]);
    return res;
}

int qmax(int x,int y){
    int res=-inf;
    while (top[x]!=top[y]){
        if (depth[top[x]]<depth[top[y]]){
            swap(x,y);
        }
        res=max(res,query_max(1,1,n,dfn[top[x]],dfn[x]));
        x=fa[top[x]];
    }
    if (depth[x]>depth[y]) swap(x,y);
    if (x!=y) res=max(res,query_max(1,1,n,dfn[x]+1,dfn[y]));
    return res;
}

int qmin(int x,int y){
    int res=inf;
    while (top[x]!=top[y]){
        if (depth[top[x]]<depth[top[y]]){
            swap(x,y);
        }
        res=min(res,query_min(1,1,n,dfn[top[x]],dfn[x]));
        x=fa[top[x]];
    }
    if (depth[x]>depth[y]) swap(x,y);
    if (x!=y) res=min(res,query_min(1,1,n,dfn[x]+1,dfn[y]));
    return res;
}

void uchain(int x,int y){
    while (top[x]!=top[y]){
        if (depth[top[x]]<depth[top[y]]){
            swap(x,y);
        }
        update(1,1,n,dfn[top[x]],dfn[x]);
        x=fa[top[x]];
    }
    if (depth[x]>depth[y]) swap(x,y);
    if (x!=y) update(1,1,n,dfn[x]+1,dfn[y]);
}

void upoint(int x,int val){
    int p=x*2-1;
    int u=e[p].v,v=e[p^1].v;
    if (fa[u]==v) swap(u,v);
    change(1,1,n,dfn[v],val);
}

int main(){
    freopen("/Users/liyumei1973/Downloads/P1505_10.in","r",stdin);
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    memset(p,-1,sizeof p);

    cin >> n;
    for (int i=1,u,v,w;i<n;i++){
        cin >> u >> v >> w;
        add(u,v,w),add(v,u,w);
    }
    cin >> m;

    dfs1(0,-1);
    dfs2(0,0);
    build(1,1,n);
    string opt;
    int u,v,w,i;
    
    while (m--){
        cin >> opt;
        if (opt=="C"){
            cin >> i >> w;
            upoint(i,w);
        }
        else if (opt=="N"){
            cin >> u >> v;
            uchain(u,v);
        }
        else if (opt=="SUM"){
            cin >> u >> v;
            cout << qsum(u,v) << endl;
        }
        else if (opt=="MAX"){
            cin >> u >> v;
            cout << qmax(u,v) << endl;
        }
        else{
            cin >> u >> v;
            cout << qmin(u,v) << endl;
        }
    }

    return 0;
}
但是如果,main()函数中的dfs1和dfs2使用的根节点不是0,而是1或者其他 就像这样
CPP
dfs1(1,-1);
dfs2(1,1);
build(1,1,n);
就会RE两个点R68816185
改了其他数更甚R68816726
我不李姐啊???? 求大佬解释,谢谢!

回复

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

正在加载回复...