首页 > 代码库 > UESTC 889 Battle for Silver (dfs)

UESTC 889 Battle for Silver (dfs)

题意:

给一个图,每个点有点权,每两个点最多有一条边相连,每个点至少和一个点通过边相连。

要找出这样一个团,使得团内所有的点两两都有边相连且边不交叉,并且点权最大。


算法:

由于两两连边且边不能交叉,可知最多有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)