1093 - Castles

Wars have played a significant role in world history. Unlike modern wars, armies in the middle ages were principally concerned with capturing and holding castles, the private fortified residences of lords and nobles. The size of the attacking army was an important factor in an army's ability to capture and hold one of these architectural masterpieces.

\epsfbox{p4788.eps}

A certain minimum number of soldiers were required to capture a castle. Some soldiers were expected to die during the attack. After capturing the castle, some soldiers were required to remain in the castle to defend it against attacks from another enemy. Of course, those numbers were different for different castles. Commanders of the armies were obliged to consider the number of soldiers required for victory. For example, there are five castles in the region map shown in Figure 2. The castle at the lower right requires at least 20 soldiers to wage a winning attack. None are expected to perish during the attack, and 10 soldiers must be left in the castle when the army moves on.


In this problem you must determine the minimum size of an army needed to capture and hold all the castles in a particular region. For reasons of security, there is exactly one (bi-directional) route between any pair of castles in the region. Moving into the neighborhood of an uncaptured castle begins an attack on that castle. Any castle can serve as the first castle to be attacked, without regard for how the army got there. Once any castle has been captured, the requisite number of soldiers is left in the castle to defend it, and the remainder of the army moves on to do battle at another castle, if any remain uncaptured. The army may safely pass through the neighborhood of a castle that it has already captured. But because of the potential for attacks, the army may traverse the route between a pair of castles no more than twice (that is, at most once in each direction).

Input 

The input contains multiple test cases corresponding to different regions. The description of the castles in each region occupies several lines. The first line contains an integer n$ \le$100 that is the number of castles in the region. Each of the next n lines contains three integers am, and g (1$ \le$a$ \le$1000, 0$ \le$m$ \le$a, 1$ \le$g$ \le$1000), that give the minimum number of soldiers required to successfully attack and capture a particular castle, the number of soldiers that are expected to die during the attack, and the number of soldiers that must be left at the castle to defend it. The castles are numbered 1 to n, and the input lines describing them are given in increasing order of castle numbers. Each of the remaining n - 1 lines in a test case has two integers that specify the castle numbers of a pair of castles that are connected by a direct route.

A line containing 0 follows the description of the last region.

Output 

For each test case, display the case number and the minimum number of soldiers in the army needed to conquer all the castles in the region. Follow the format shown in the sample output.

Sample Input 

3 
5 5 5 
10 5 5 
5 1 1 
1 3 
2 3 
5 
10 5 10 
20 10 5 
10 10 5 
5 5 5 
20 0 10 
1 2 
1 3 
1 4 
3 5 
0

Sample Output 

Case 1: 22 
Case 2: 65








#include<iostream>
#include<vector>
#include<string.h>
#include<string>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int MaxN=109;
const int INF=1000000000;
int N,M;
vector<int> e[MaxN];
vector<pair<int,int>> Go[MaxN];
int A[MaxN],B[MaxN],F[MaxN],G[MaxN];

void init()
{
	for(int i=1;i<=N;i++)
		e[i].clear();
	for(int i=1;i<=N;i++)
	{
		int x;
		scanf("%d%d%d",&A[i],&B[i],&x);
		B[i]+=x;
		if(A[i]>=B[i]);
		else
			A[i]=B[i];
	}
	for(int i=1;i<N;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
}

void Dfs(int fa,int x)
{
	F[x]=A[x];
	G[x]=B[x];
	Go[x].clear();
	for(int i=0;i<e[x].size();i++)
		if(e[x][i]!=fa)
		{
			Dfs(x,e[x][i]);
			Go[x].push_back(make_pair(G[e[x][i]],F[e[x][i]]));
		}
	sort(Go[x].begin(),Go[x].end());
	for(int i=Go[x].size()-1;i>=0;i--)
	{
		if(F[x]-G[x]<Go[x][i].second)
			F[x]=G[x]+Go[x][i].second;
		G[x]+=Go[x][i].first;
	}
}

void solve()
{
	int ans=INF;
	for(int i=1;i<=N;i++)
	{
		for(int j=1;j<=N;j++)
			F[j]=G[j]=-1;
		Dfs(0,i);
		if(F[i]<ans)
			ans=F[i];
	}
	printf("%d\n",ans);
}

int main()
{
	int T=0;
	while(1==scanf("%d",&N)&&N!=0)
	{
		T++;
		init();
		printf("Case %d: ",T);
		solve();
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值