一题不怎么明显的爆搜,刚刚看到题还以为是点覆盖,但是发现转不成二分树,DP也没什么思路,最后只能爆搜。搜点不是很容易,试着搜边。用vis[]
数组记录了某点是否被滴过,在搜边时如果两端点又被滴过的直接搜下一个点;若两端点都未搜过则枚举其中一个,然后回溯枚举另一个。
其中sum>10可以剪枝,最后看ans与10的关系,
复杂度(2^10*m)

以下为AC代码

#define Maxx 2005
#include<bits/stdc++.h>
using namespace std;
struct node{
    int x,y;
}a[Maxx];

int t,n,m,ans;
int vis[Maxx];

void dfs(int u,int sum){
    if(sum>10)return;
    if(u==m){
        ans=min(ans,sum);
        return;
    }
    int xx=a[u].x,yy=a[u].y;
    if(vis[xx]||vis[yy])dfs(u+1,sum);
    else{
        vis[xx]=1;
        dfs(u+1,sum+1);
        vis[xx]=0;
        vis[yy]=1;
        dfs(u+1,sum+1);
        vis[yy]=0;
    }
    return;
}

int main(){
    cin>>t;
    while(t--){
        memset(vis,0,sizeof(vis));
        ans=0x3f3f3f3f;
        cin>>n>>m;
        for(int i=0;i<m;i++){
            cin>>a[i].x>>a[i].y;
        }
        dfs(0,0);
            if(ans<=10)cout<<ans<<endl;
            else cout<<"GG"<<endl;
    }
    return 0;
}