求助
  • 板块P1364 医院设置
  • 楼主emo_zkt
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/11/20 14:08
  • 上次更新2024/11/20 16:29:56
查看原帖
求助
482163
emo_zkt楼主2024/11/20 14:08

60分,用的树上DP的二次扫描与换根方法

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
const int INF=0x3f3f3f3f;
int head[N],tot=-1,n,l,r,w[N],dis[N],vis[N],dep[N],sz[N],dp[N],sum;
int ans,ma=INF;
queue<int> q;
struct nod{
    int ne,to,w;
}e[N*2];
void add(int u,int v,int w){
    e[++tot].ne=head[u];
    e[tot].to=v;
    e[tot].w=w;
    head[u]=tot;
}
void dfs1(int u,int fa){
    sz[u]=1;
    for(int i=head[u];i!=-1;i=e[i].ne){
        int v=e[i].to;
        if(v==fa)continue;
        dfs1(v,u);
        sz[u]+=sz[v];
    }
}
void dfs2(int u,int fa){
    for(int i=head[u];i!=-1;i=e[i].ne){
        int v=e[i].to;
        if(v==fa)continue;
        dp[v]=dp[u]+n-2*sz[v];
        dfs2(v,u);
    }
}
void bfs(int s){
	memset(dis,0x3f,sizeof dis);
	q.push(s);
	dis[s]=0,vis[s]=1;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(int i=head[u];i!=-1;i=e[i].ne){
			int v=e[i].to;
			if(vis[v]==0){
				vis[v]=1,dis[v]=dis[u]+1;
				q.push(v);
			}
		}
	}
}
int main(){
    cin>>n;
    memset(head,-1,sizeof head);
    for(int i=1;i<=n;i++){
        cin>>w[i]>>l>>r;
        if(l!=0)add(i,l,1),add(l,i,1);
        if(r!=0)add(i,r,1),add(r,i,1);
    }
    dfs1(1,1);
    dfs2(1,1);
    for(int i=1;i<=n;i++){
        if(dp[i]<ma){
            ma=dp[i];
            ans=i;
        }
    }
    //cout<<"_____________here______________";
    bfs(ans);
    for(int i=1;i<=n;i++)sum+=w[i]*dis[i];
    cout<<sum;
    return 0;
}
2024/11/20 14:08
加载中...