HDU 3848 CC On The Tree

http://acm.hdu.edu.cn/showproblem.php?pid=3848

#include<iostream>
#define N 10005
using namespace std;
#define inf 0x7fffffff
struct node{
	int next,v,w;
	node(){};
	node(int a,int b,int c){
		next=a;v=b;w=c;
	}
}E[2*N];
bool h[N];
int head[N],NE,in[N];
int dp_f[N],dp_s[N];
void init(){
	NE=0;
	memset(head,-1,sizeof(head));
	memset(in,0,sizeof(in));
	memset(h,0,sizeof(h));
}
void insert(int u,int v,int w){
	E[NE]=node(head[u],v,w);
	head[u]=NE++;
}
int dfs(int u){
	int M1,M2;
	M1=M2=inf;
	h[u]=1;
	for(int i=head[u];i!=-1;i=E[i].next){
		int v=E[i].v;
		if(h[v]) continue;
		int w=dfs(v);
		if(w+E[i].w<M1){
			M2=M1;
			M1=w+E[i].w;
		}
		else if(w+E[i].w==M1)
			M2=M1;
		else if(w+E[i].w<M2)
			M2=w+E[i].w;
	}
	if(in[u]==1){
		dp_f[u]=0;
		dp_s[u]=0;
	}
	else{
		dp_f[u]=M1;
		dp_s[u]=M2;
	}
	return dp_f[u];
}
int GetInt(){
    char ch=getchar();
    while(ch<'0'||ch>'9')ch=getchar();
    int num=0;
    while(ch>='0'&&ch<='9'){
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num;
}
int main(void){
	int n;
	while(scanf("%d",&n),n){
		init();
		int u,v,w;
		for(int i=1;i<n;i++){		
			u=GetInt();
			v=GetInt();
			w=GetInt();
			in[u]++;in[v]++;
			insert(u,v,w);
			insert(v,u,w);
		}
		if(n==2){
			printf("%d\n",w);
			continue;
		}
		int Max=-1;
		for(int i=1;i<=n;i++)
			if(in[i]>Max){
				Max=in[i];
				u=i;
			}
		dfs(u);
		int Min=inf;
		for(int i=1;i<=n;i++)
			if(in[i]>=2&&dp_f[i]!=inf&&dp_s[i]!=inf&&dp_f[i]+dp_s[i]<Min)
				Min=dp_f[i]+dp_s[i];
		printf("%d\n",Min);
	}
}

树形dpdpdp.....做了2196那题,再做这个就比较好做了,别忘记最后还要扫一遍。。。开两个dp数组,记录最小和次小两个值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值