一个看似正确实则暗藏“玄机”的算法
查看原帖
一个看似正确实则暗藏“玄机”的算法
112133
雨落星尘楼主2020/8/29 22:46

第九个点一直WA,一看输出了负数,本地却一直在dfs1无限循环了……

#include<bits/stdc++.h>

namespace solve{
	#define N 100005
	#define ull unsigned long long
	
	int n,ui,vi,wi,cnt;
	ull ans;
	ull F[N],scow[N];
	int head[N],dep[N],cow[N];
	
	struct ed{
		int nxt,to,w;
	}e[2*N];
	
	int read(){
		char c;
		int x=0,f=1;
		while((c=getchar())<'0'||c>'9')if(c=='-')f=-1;
		while(c<='9'&&c>='0'){
			x=(x<<3)+(x<<1)+(c^48);
			c=getchar();
		}
		return f*x;
	}
	
	void add(int u,int v,int w){
		e[++cnt]=(ed){head[u],v,w};
		head[u]=cnt;
		e[++cnt]=(ed){head[v],u,w};
		head[v]=cnt;
	}
	
	void dfs1(int u,int f){
		for(int i=head[u];i;i=e[i].nxt){
			int v=e[i].to,w=e[i].w;
			if(v==f||F[v])continue;
			dep[v]=dep[u]+w;
			F[v]=dep[v]*cow[v];
			dfs1(v,u);
			scow[u]+=scow[v];
			F[u]+=F[v];
		}
	}
	
	void dfs2(int u,int f){
		for(int i=head[u];i;i=e[i].nxt){
			int v=e[i].to,w=e[i].w;
			if(v==f)continue;
			F[v]=F[u]-scow[v]*w*2+scow[1]*w;
			//printf("test:F[%d]=%lld\n",v,F[v]);
			if(F[v]<ans)ans=F[v];
			dfs2(v,u);
		}
	}
	
	void init(){
		n=read();
		for(int i=1;i<=n;i++){
			cow[i]=read();
			scow[i]=cow[i];
		}
		for(int i=1;i<n;i++){
			ui=read();
			vi=read();
			wi=read();
			add(ui,vi,wi);
		}
		dfs1(1,-1);
		ans=F[1];
		dfs2(1,-1);
		printf("%llu\n",ans);
	}
}

int main(void){
	solve::init();
	return 0;
}
2020/8/29 22:46
加载中...