TopCoder SRM 140 Div2 第3题

类型:图论 难度:2

题意:发电站和各级变压器构成一棵树的节点,发电站为根节点。现在需要从根节点出发,沿树边检查每个节点,必要时回溯,检查完最后一个节点立即终止,给出每条边的耗时/路径长,求最短耗时/最短路径。


分析:由于要遍历所有节点,所有假设根节点有n个子树,只有走最后一棵子树时不用回溯到根节点。其余n-1棵子树均需回到根节点,则其余n-1棵子树所走的路径长即为:(每棵子树的路径和+根节点到该儿子的路径)*2,而第n棵子树的路径长即为:根节点到该儿子的路径+将该点作为根节点继续递归求解的路径。所以一开始以递归问题做的。但是不难发现,整体上看,走完所有节点后,只有一条从根节点到叶子节点的路径走了1次,其余所有路径均走了两次,而这条路径即为所有从根节点到叶子节点的路径中最长的路径,所以问题转化为找此最长路径,再用 总路径长*2-最长路径 即为所求,思路更简单。

具体实现上,用dfs遍历记录每个根节点到叶子的路径长,选最大即可


代码如下:

#include<cstring>
#include<string>
#include<cstdio>
#include<sstream>
#include<iostream>
#include<vector>
#include<map>
using namespace std;

const int MAX = 55;

class PowerOutage
{
	public:	
		
		int par[MAX],chd[MAX],bro[MAX],len[MAX];
		int edge[MAX][MAX];
		int maxlen;
		
		void dfs(int root)
		{
			for(int i=chd[root]; i>=0; i=bro[i])
			{
				len[i] = len[root]+edge[root][i];
				if(chd[i] < 0)
				{
					if(len[i] > maxlen)
						maxlen = len[i];
				}
				else
					dfs(i);
			}			
		}
		
		int estimateTimeOut(vector <int> fromJunction, vector <int> toJunction, vector <int> ductLength)
		{	
			int n=fromJunction.size();
			int i;
			int sumlen=0;
			
			memset(par,-1,sizeof(par));
			memset(chd,-1,sizeof(chd));
			memset(bro,-1,sizeof(bro));
			memset(len,0,sizeof(len));
			memset(edge,-1,sizeof(edge));
			
			for(i=0; i<n; i++)
			{
				par[toJunction[i]] = fromJunction[i];					
				if(chd[fromJunction[i]] >= 0)
				{
					bro[toJunction[i]] = chd[fromJunction[i]];
				}
				chd[fromJunction[i]] = toJunction[i];
				edge[fromJunction[i]][toJunction[i]] = ductLength[i];
				sumlen += ductLength[i];
			}
			
			maxlen = 0;
			dfs(0);
						
			return sumlen*2-maxlen;
		}
};


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值