首页 > 其他 > 详细

HDU 3339 In Action 价值为最短路的背包

时间:2014-04-06 08:40:44      阅读:376      评论:0      收藏:0      [点我收藏+]

题目来源:HDU 3339 In Action

题意:有一个系统要去破坏 该系统是有n个点组成的图 每个点有一个权值

可以从0排除任意个机器人 去占领一个点 每个机器只能占领一个地方 所有机器人占领点的权值之和大于所有点权值之和的一半(不能等于) 就算破环成功

求在破坏的情况下所有机器人走过的路径之和最小 

思路:简而言之 就是选出若干个点 他们的和大于总数的一半 并且走的路最短

转化成背包问题 总体积为所有点权值的和 每个物品的体积是该个点的权值 价值是0到个点的距离 0到各个点的距离可以用floyd求出 最后01背包求最小值就可以了

 

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 110;
const int maxm = 10010;
int a[maxn][maxn];
int b[maxn];
int dp[maxm];
int n, m;
void floyd()
{
	for(int k = 0; k <= n; k++)
		for(int i = 0; i <= n; i++)
			for(int j = 0; j <= n; j++)
				if(a[i][j] > a[i][k] + a[k][j])
					a[i][j] = a[i][k] + a[k][j];
					
}

int main()
{
	int T;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d %d", &n, &m);
		for(int i = 0; i <= n; i++)
			for(int j = 0; j <= n; j++)
				{
					if(i == j)
						a[i][j] = 0;
					else
						a[i][j] = 99999999;
				}
		
		for(int i = 1; i <= m; i++)
		{
			int u, v, w;
			scanf("%d %d %d", &u, &v, &w);
			if(a[u][v] > w)
				a[u][v] = a[v][u] = w;
		}
		floyd();
		int sum = 0;
		for(int i = 1; i <= n; i++)
		{
			scanf("%d", &b[i]);
			sum += b[i];
		}
		//printf("%d\n", sum);
		for(int i = 1; i <= sum; i++)
			dp[i] = 99999999;
		dp[0] = 0;
		for(int i = 1; i <= n; i++)
		{
			for(int j = sum; j >= b[i]; j--)
			{
				dp[j] = min(dp[j], dp[j-b[i]]+a[0][i]);
			}
		}
		int ans = 99999999;
		for(int i = sum/2+1; i <= sum; i++)
		{
			ans = min(ans, dp[i]);
		}
		if(ans == 99999999)
			puts("impossible");
		else
			printf("%d\n", ans);
	}
	return 0;
}


 

HDU 3339 In Action 价值为最短路的背包,布布扣,bubuko.com

HDU 3339 In Action 价值为最短路的背包

原文:http://blog.csdn.net/u011686226/article/details/23002755

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!