题意:
给一个图,每个点有点权,每两个点最多有一条边相连,每个点至少和一个点通过边相连。
要找出这样一个团,使得团内所有的点两两都有边相连且边不交叉,并且点权最大。
算法:
由于两两连边且边不能交叉,可知最多有4个点。所以暴搜~
dfs出4个位置放什么元素,一边判断放的点与前面的点是否是两两连边,一边更新ans。
开始一直当做3个点和4个点在写,忘了考虑1个点和2个点。。。WA了10次。。
自己写个样例自己推结果也是没考虑1个点和2个点的情况。。
/*
6 7
1500
1000
100
2000
500
300
1 2
1 3
1 4
3 5
4 5
4 6
5 6
ans = 3500
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#define maxn 500
using namespace std;
int a[maxn],mp[maxn][maxn],v,ans;
int op[5];
bool vis[maxn];
int check(int pos,int x)
{
for(int i=0;i<pos;i++)
{
if(!mp[op[i]][x])
return 0;
}
return 1;
}
void dfs(int pos,int x,int sum)
{
ans = max(ans,sum);
if(pos==4) return;
for(int i=x+1;i<=v;i++)
{
if(vis[i] || !check(pos,i)) continue;
op[pos] = i;
vis[i] = true;
dfs(pos+1,i,sum+a[i]);
vis[i] = false;
}
}
int main()
{
int e,ta,tb;
while(scanf("%d%d",&v,&e)!=EOF)
{
memset(mp,0,sizeof(mp));
for(int i=1;i<=v;i++)
scanf("%d",&a[i]);
for(int i=1;i<=e;i++)
{
scanf("%d%d",&ta,&tb);
mp[ta][tb] = mp[tb][ta] = 1;
}
ans = 0;
dfs(0,0,0);
printf("%d\n",ans);
}
return 0;
}
UESTC 889 Battle for Silver (dfs)
原文:http://blog.csdn.net/u012841845/article/details/38866671