前面用搜索写了这题,其实这题也可以用DLX写的。
#include <iostream> #include<stdio.h> #include<cmath> #include<string.h> #include<algorithm> #include<string> #include<vector> #include <cstdlib> using namespace std; const int maxn = 510; const int maxnode= 510*510*10; int U[maxnode],D[maxnode],R[maxnode],L[maxnode],row[maxnode],col[maxnode]; struct DLX { int n,m,sz; int H[maxn],S[maxn]; int ans; void init(int n,int m) { this->n=n; this->m=m; for(int i = 0; i <= m; i++) { S[i] = 0; U[i] = D[i] = i; L[i] = i-1; R[i] = i+1; } R[m] = 0; L[0] = m; sz = m; for(int i = 1; i <= n; i++)H[i] = -1; } void Link(int r,int c) { ++S[col[++sz]=c]; row[sz] = r; U[sz] = U[c]; D[U[c]] = sz; D[sz] = c; U[c] = sz; if(H[r] < 0)H[r] = L[sz] = R[sz] = sz; else { L[sz] = L[H[r]]; R[L[H[r]]] = sz; R[sz] = H[r]; L[H[r]] = sz; } } #define FOR(i,A,s) for(int i=A[s];i!=s;i=A[i]) void remove(int c) { FOR(i,D,c) { L[R[i]]=L[i]; R[L[i]]=R[i]; } } void restore(int c) { FOR(i,U,c) { L[R[i]]=i; R[L[i]]=i; } } bool v[maxnode]; int f() { int ret = 0; for(int c = R[0]; c != 0; c = R[c]) v[c] = true; for(int c = R[0]; c != 0; c = R[c]) if(v[c]) { ret++; v[c] = false; for(int i = D[c]; i != c; i = D[i]) for(int j = R[i]; j != i; j = R[j]) v[col[j]] = false; } return ret; } void dfs(int d) { if(d+f()>=ans) return ; if(R[0]==0) { ans=min(ans,d); return ; } int c=R[0]; FOR(i,R,0) if(S[i]<S[c]) c=i; FOR(i,D,c) { remove(i); FOR(j,R,i) remove(j); dfs(d+1); FOR(j,L,i) restore(j); restore(i); } return; } int solve() { dfs(0); return ans; } }; const int mmax = 510; struct node { int en; int next; }E[mmax*mmax]; int p[mmax]; int num; void init() { memset(p,-1,sizeof p); num=0; }; void add(int st,int en) { E[num].en=en; E[num].next=p[st]; p[st]=num++; } int main() { int n,m; while(~scanf("%d %d",&n,&m)) { init(); for(int i=0;i<m;i++) { int u,v; scanf("%d %d",&u,&v); add(u,v); add(v,u); } DLX X; X.init(n,m); for(int i=1;i<=n;i++) { for(int j=p[i];j+1;j=E[j].next) X.Link(i,j/2+1); } X.ans=min(30,n); printf("%d\n",X.solve()); } return 0; }