ZOJ 3684 Destroy

首先中心應當位於整棵樹的直徑上,先從任意點開始搜一條最長路徑,該路徑的終點必是直徑的一段,以上結論由反證可推出矛盾。再從端點開始深搜可得直徑,遍歷該路徑即可得到中心點所在。接下來以中心點爲根節點,開始DP即可。


#include <map>
#include <cstdio>
#include <memory.h>
using namespace std;
#define it map<int,road>::iterator

struct road
{
	int l, p;
} t;

map<int, road> a[10001];
int pole;
int lmax;
int n;

int temp;
inline int maxlen(int length)
{
	temp = lmax - length;
	return length>temp?length:temp;
}
inline int minimum(int a, int b)
{
	return a<b?a:b;
}

void dfs(int cur, int pre, int len)
{
	bool end = true;
	for(it i=a[cur].begin(); i!=a[cur].end(); ++i)
	{
		if(i->first != pre)
		{
			end = false;
			dfs(i->first, cur, len+i->second.l);
		}
	}
	if(end && len>lmax)
	{
		lmax = len;
		pole = cur;
	}
}

int stack[10000], top;
int path[10000], plen;
void dfs1(int cur, int pre, int len)
{
	stack[top++] = cur;
	bool end = true;
	for(it i=a[cur].begin(); i!=a[cur].end(); ++i)
	{
		if(i->first != pre)
		{
			end = false;
			dfs1(i->first, cur, len+i->second.l); //bug2: dfs->dfs1
		}
	}
	if(end && len>lmax)
	{
		lmax = len;
		pole = cur;
		plen = top;
		memcpy(path, stack, top*sizeof(int));
	}
	-- top;
}

int dfs2(int cur, int pre)
{
	int min, maxmin = -1;
	bool end = true;
	for(it i=a[cur].begin(); i!=a[cur].end(); ++i)
	{
		if(i->first != pre)
		{
			end = false;
			min = minimum(i->second.p, dfs2(i->first, cur));
			if(min > maxmin)
				maxmin = min;
		}
	}
	if(end == true) return 100000000;
	else	return maxmin;
}


int main()
{
	int ind, ind0;
	while(scanf("%d", &n) != EOF)
	{
		for(int i=1; i<n; ++i)
		{
			scanf("%d%d%d%d", &ind, &ind0, &t.l, &t.p);
			a[ind][ind0] = t;
			a[ind0][ind] = t;
		}

		lmax = -1;
		dfs(1, 0, 0);

		lmax = -1, top=0;
		dfs1(pole, 0, 0);

		int middle, length=0;
		int minmax = 99999999;
		for(int k=1; k<plen; ++k)
		{
			length += a[path[k]][path[k-1]].l; //bug1: k->path[k]...
			if(maxlen(length) < minmax)
			{
				minmax = maxlen(length);
				middle = path[k];
			}
		}

		printf("%d\n", dfs2(middle, 0));
		for(int j=1; j<=n; ++j)
			a[j].clear();
	}
	return 0;
}


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