Fleet Commander
Source : HCPC 2004 | |||
Time limit : 5 sec | Memory limit : 32 M |
Submitted : 196, Accepted : 77
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);
}
}