pku_3140_Contestants Division

數據特別坑爹,題特別簡單~

一個樹的dfs完事.

題目大意:

一棵樹,每個點有點權值,問刪掉一條邊後剩餘的兩棵樹總權值差最小.每個點範圍在100000000.....尼瑪這數據得多坑爹~

除了題意不好看懂外~還有一點數據要注意~最後求和的時候要用LLONG_MAX,不然根本不夠~然後沒有難點了~虧得我還當樹形DP做呢~

源代碼:

#include <myhead.h>

const int N=100010;
int n,m;
LL sum;
bool make[N];
LL value[N];
LL dp[N];
vector<int> node[N];

void init() {
	sum=0;
	memset(make,false,sizeof(make));
	memset(dp,0,sizeof(dp));
	for(int i=0;i<=n;++i) {
		node[i].clear();
	}
	for(int i=1;i<=n;++i) {
		scanf("%lld",&value[i]);
		sum+=value[i];
	}
	int x,y;
	for(int i=0;i<m;++i) {
		scanf("%d%d",&x,&y);
		node[x].push_back(y);
		node[y].push_back(x);
	}

}

LL dfs(int x) {
	make[x]=true;
	dp[x]=value[x];
	for(int i=0;i<node[x].size();++i) {
		if(!make[node[x][i]]) {
			dp[x]+=dfs(node[x][i]);
		}
	}
	return dp[x];
}

void work() {
	dp[1]=dfs(1);
	//printf("%lld,%lld\n",sum,dp[1]);
	LL t,ans=LLONG_MAX;//數據這個大啊~
	for(int i=1;i<=n;++i) {
		//printf("%lld ",dp[i]);
		t=sum-(dp[i]<<1);
		if(t<0) t=-t;
		checkmin(ans,t);
	}
	//puts("");
	printf("%lld\n",ans);
}

int main() {
	int t=1;
	while(~scanf("%d%d",&n,&m),n+m) {
		init();
		printf("Case %d: ",t++);
		work();
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章