HOJ 1487 Fleet Commander

Fleet Commander

My Tags  (Edit)
  Source : HCPC 2004
  Time limit : 5 sec   Memory limit : 32 M

Submitted : 196, Accepted : 77

 """ Fight for freedom, Fight for honor!

In June 6, 2044, the main force of country Z's United Fleet encountered the main force of country M's Pacific Fleet. And the battle started.

At the beginning of the battle, the both sides lost a few ships, and some ships lost contact to some other ones. 1 hour later, the commander of United Fleet-you, made a design: Forming a special fleet with the most power to attack the enemy's back. And in the special fleet, every ship can keep in touch with any other ones. 

"""

Given the situation of your fleet, you were to build the special fleet and calculate its power.

Input

There are multiple test cases. In the first line of each test case, two integers n (0 < n < 100) and m show the number of your ships and how many contacts are lost between the ships, separated by a blank. The followed n lines of integers indicate one ship's power (from 0 to n-1). Each of the followed m lines contains the numbers of the two ships, which can not contact with each other. The input end with n=0 and m=0.

Output

For each test case, you should output:"Case ",the case number, ": ", and the max power you can get in a single line.

Sample Input

4 1
25
37
14
15
2 3
3 3
98
99
100
0 1
2 0
2 1
0 0

Sample Output

Case 1: 77
Case 2: 100

题意:现在有好多条船,每条船有对应的战斗力,但是有些船之间不能相互通信,要求找出一个集合,使得当中的船互相之间能够通信,并且战斗力总和要最大。


思路:直接深搜吧,剪枝有如果当前的战斗力,加上剩余的战斗力都不能比答案更优,可以剪枝,如果这艘船能和所有的船通信,那么这艘船就直接被选中了。。。



代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<string.h>
#include<stack>
using namespace std;

const int maxn = 110;

struct Node 
{
	int v;
	Node *next;
} * first[maxn] , edge[maxn*maxn];

int ptr , ans , sum , n , m , w[maxn];
bool vis[maxn];

void add(int x,int y)
{
	edge[++ptr].v = y;
	edge[ptr].next = first[x];
	first[x] = &edge[ptr];
}

void init()
{
	ptr = sum = ans = 0;
	memset(first,0,sizeof(first));
	memset(edge,0,sizeof(edge));
}

void input()
{
	for (int i = 0 ; i < n ; ++i)
	{
		scanf("%d",w+i);
		sum += w[i];
	}
	while (m--)
	{
		int x , y;
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
	}
}

void dfs(int x,int val,int rest)
{
	if (val+rest<=ans) return;
	if (val > ans) ans = val;
	if (first[x]==NULL)
	{
		dfs(x+1,val+w[x],rest-w[x]);
		return;
	}
	dfs(x+1,val,rest-w[x]);
	if (vis[x]) return;
	Node * p = first[x];
	stack<int> stk;
	while (p)
	{
		int y = p->v;
		if (!vis[y])
		{
			vis[y] = true;
			stk.push(y);
		}
		p = p->next;
	}
	dfs(x+1,val+w[x],rest-w[x]);
	while (stk.size())
	{
		int y = stk.top(); stk.pop();
		vis[y] = false;
	}
}

void solve()
{
	memset(vis,0,sizeof(vis));
	dfs(0,0,sum);
}

int main()
{
	int Cas = 0;
	while (scanf("%d%d",&n,&m),n+m)
	{
		++Cas;
		init();
		input();
		solve();
		printf("Case %d: %d\n",Cas,ans);
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值