[toc]
一下题目可以套白书模板
UVA 1309 Sudoku
把Sudoku上的点拆成如下信息
(r,c)
是否填了
(r,v),(c,v),(s,v)
第r行/c列/s块是否填了v
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
struct DLX {
#define maxn (10000000+10)
#define MAXNode (10000000+10)
#define maxr (10000000)
int n, sz;
int S[maxn];
int row[MAXNode],col[MAXNode];
int L[MAXNode],R[MAXNode],U[MAXNode],D[MAXNode];
int ansd, ans[maxr];
void init(int n) {
this->n = n;
Rep(i,n+1) {
U[i] = D[i] = i ; L[i]=i-1; R[i]=i+1;
}
R[n]=0; L[0]=n;
sz=n+1;
MEM(S)
}
void addRow(int r, vi columns) {
int fir = sz;
int cSz=columns.size();
Rep(i,cSz) {
int c=columns[i];
L[sz] = sz-1; R[sz] = sz+1; D[sz] = c; U[sz] = U[c];
D[ U[c] ] =sz; U[c]=sz;
row[sz] = r; col[sz] = c;
S[c]++; sz++;
}
R[sz-1]=fir; L[fir] = sz-1;
}
#define FOR(i,A,s) for(int i=A[s];i!=s;i=A[i])
void remove(int c) {
L[R[c]] = L[c];
R[L[c]] = R[c];
FOR(i,D,c)
FOR(j,R,i) {
U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]];
}
}
void restore(int c) {
FOR(i,U,c)
FOR(j,L,i) {
++S[col[j]];
U[D[j]] = j;
D[U[j]] = j;
}
L[R[c]]=c;
R[L[c]]=c;
}
bool dfs(int d) {
if ( R[0] == 0) {
ansd = d;
return 1;
}
int c = R[0];
FOR(i,R,0) if (S[i] < S[c]) c = i;
remove(c);
FOR(i,D,c) {
ans[d] = row[i];
FOR(j,R,i) remove(col[j]);
if (dfs(d+1)) return 1;
FOR(j,L,i) restore(col[j]);
}
restore(c);
return 0;
}
bool solve(vi &v) {
v.clear();
if (!dfs(0)) return 0;
Rep(i,ansd) v.pb(ans[i]);
return 1;
}
};
DLX solver;
char puzzle[16][20];
bool init() {
Rep(i,16) {
if (scanf("%s",puzzle[i])!=1) return 0;
}
return 1;
}
const int SLOT = 0;
const int ROW = 1;
const int COL = 2;
const int SUB = 3;
int encode(int a,int b,int c) {
return a*16*16+b*16+c+1;
}
void decode(int code,int &a,int &b,int &c) {
code--;
c=code%16; code/=16;
b=code%16; code/=16;
a=code;
}
int main()
{
// freopen("uva1309.in","r",stdin);
// freopen(".out","w",stdout);
bool fl=0;
while(init()) {
if (fl) puts(""); fl=1;
solver.init(1024);
Rep(r,16) Rep(c,16) Rep(v,16) { // put v in (r,c)
if (puzzle[r][c]=='-'||puzzle[r][c]=='A'+v) {
vi columns;
columns.pb(encode(SLOT,r,c));
columns.pb(encode(ROW,r,v));
columns.pb(encode(COL,c,v));
columns.pb(encode(SUB,r/4*4+c/4,v));
solver.addRow(encode(r,c,v),columns);
}
}
vi ans;
solver.solve(ans);
int sz=SI(ans);
Rep(i,sz) {
int a,b,c;
decode(ans[i],a,b,c);
puzzle[a][b]=c+'A';
}
Rep(r,16) puts(puzzle[r]);
}
return 0;
}
UVA 1469 Sudoku Extension
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
struct DLX {
#define maxn (10000000+10)
#define MAXNode (10000000+10)
#define maxr (10000000)
int n, sz;
int S[maxn];
int row[MAXNode],col[MAXNode];
int L[MAXNode],R[MAXNode],U[MAXNode],D[MAXNode];
int ansd, ans[maxr];
void init(int n) {
this->n = n;
Rep(i,n+1) {
U[i] = D[i] = i ; L[i]=i-1; R[i]=i+1;
}
R[n]=0; L[0]=n;
sz=n+1;
MEM(S)
}
void addRow(int r, vi columns) {
int fir = sz;
int cSz=columns.size();
Rep(i,cSz) {
int c=columns[i];
L[sz] = sz-1; R[sz] = sz+1; D[sz] = c; U[sz] = U[c];
D[ U[c] ] =sz; U[c]=sz;
row[sz] = r; col[sz] = c;
S[c]++; sz++;
}
R[sz-1]=fir; L[fir] = sz-1;
}
#define FOR(i,A,s) for(int i=A[s];i!=s;i=A[i])
void remove(int c) {
L[R[c]] = L[c];
R[L[c]] = R[c];
FOR(i,D,c)
FOR(j,R,i) {
U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]];
}
}
void restore(int c) {
FOR(i,U,c)
FOR(j,L,i) {
++S[col[j]];
U[D[j]] = j;
D[U[j]] = j;
}
L[R[c]]=c;
R[L[c]]=c;
}
int t;
bool dfs(int d) {
if ( R[0] == 0) {
ansd = d;
++t;
return 1;
}
int c = R[0];
FOR(i,R,0)
if (S[i] < S[c])
c = i;
remove(c);
FOR(i,D,c) {
ans[d] = row[i];
FOR(j,R,i) remove(col[j]);
dfs(d+1);
FOR(j,L,i) restore(col[j]);
}
restore(c);
return 0;
}
bool solve() {
t=0;
if (!dfs(0)) return 0;
return 1;
}
};
DLX solver;
const int N= 9;
const int SQN= 3;
char puzzle[N+10][N+10];
bool init() {
Rep(i,N) {
if (scanf("%s",puzzle[i])!=1) return 0;
}
return 1;
}
const int SLOT = 0;
const int ROW = 1;
const int COL = 2;
const int SUB = 3;
int encode(int a,int b,int c) {
return a*N*N+b*N+c+1;
}
int encode2(int a,int b) {
return 729+a*N+b+1;
}
void decode(int code,int &a,int &b,int &c) {
code--;
c=code%N; code/=N;
b=code%N; code/=N;
a=code;
}
void decode2(int code,int &a,int &b) {
code-=729+1;
b=code%N; code/=N;
a=code;
}
int main()
{
// freopen("uva1461.in","r",stdin);
// freopen(".out","w",stdout);
int T=read();
while(init()&&T--) {
solver.init(N*N*4);
Rep(r,N) Rep(c,N) Rep(v,N) { // put v in (r,c)
if (puzzle[r][c]=='0'||puzzle[r][c]=='1'+v||(puzzle[r][c]=='e'&&v%2==1) ||(puzzle[r][c]=='o'&&v%2==0) ) {
vi columns;
columns.pb(encode(SLOT,r,c));
columns.pb(encode(ROW,r,v));
columns.pb(encode(COL,c,v));
columns.pb(encode(SUB,r/SQN*SQN+c/SQN,v));
solver.addRow(encode(r,c,v),columns);
}
}
vi col[26][9];
Rep(r,N) Rep(c,N) if (islower(puzzle[r][c])&&puzzle[r][c]!='e'&&puzzle[r][c]!='o') {
Rep(v,N){
int t=puzzle[r][c]-'a';
col[t][v].pb(encode(SLOT,r,c));
col[t][v].pb(encode(ROW,r,v));
col[t][v].pb(encode(COL,c,v));
col[t][v].pb(encode(SUB,r/SQN*SQN+c/SQN,v));
}
}
Rep(t,26) Rep(v,N) if (!col[t][v].empty())
{
solver.addRow(encode2(t,v),col[t][v]);
}
solver.solve();
cout<<solver.t<<endl;
}
return 0;
}
HDU 3498 whosyourdaddy
题目大意:一张无向图n<=55选至少几个点,使每条边至少有一个端点为所选点。
最小可支配集
DLX也可以用来解决重复覆盖问题,但是要加一个估价函数
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
namespace solver {
#define maxn (50+10)
#define MAXNode (10000+10)
#define maxr (50+10)
int n, sz;
int S[maxn], H[maxr];
int row[MAXNode],col[MAXNode];
int L[MAXNode],R[MAXNode],U[MAXNode],D[MAXNode];
int ansd, ans[maxr];
void init(int n) {
Rep(i,n+1) {
U[i] = D[i] = i ; L[i]=i-1; R[i]=i+1; S[i]=0;
}
R[n]=0; L[0]=n;
sz=n+1;
memset(H,-1,sizeof(H));
}
void link(int r,int c) {
U[sz] = c; D[sz] = D[c];
U[D[c]] = sz; D[c] = sz;
if (H[r]<0) H[r] = L[sz] = R[sz] = sz;
else {
L[sz] = H[r];
R[sz] = R[H[r]];
L[R[H[r]]] = sz ; R[H[r]] = sz;
}
S[c]++;
col[sz] = c;
sz++;
}
#define FOR(i,A,s) for(int i=A[s];i!=s;i=A[i])
void remove(int c) {
FOR(j,D,c) {
L[R[j]] = L[j]; R[L[j]] = R[j];
}
}
void restore(int c) {
FOR(j,U,c) {
L[R[j]] = R[L[j]] = j;
}
}
//evaluation function
bool vis[maxn];
int A() {
int ret=0;
MEM(vis)
FOR(i,R,0) {
if (!vis[i]) {
vis[i]=1;
++ret;
FOR(j,D,i)
FOR(k,R,j)
vis[col[k]] = 1;
}
}
return ret;
}
void dfs(int d) {
if ( R[0] == 0) {
ansd = min(ansd,d);
return;
}
if (d+A()>=ansd) 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);//,--S[col[j]];
dfs(d+1);
FOR(j,L,i) restore(j);//,++S[col[j]];
restore(i);
}
return;
}
bool solve() {
ansd=INF;
dfs(0);
if (ansd==INF) return 0;
return 1;
}
};
int a,b;
int n,m;
bool f[60][60];
int main()
{
// freopen("hdu3498_data.in","r",stdin);
// freopen("hdu3498.out","w",stdout);
while(~scanf("%d%d",&n,&m)) {
solver::init(n);
For(i,n) For(j,n) f[i][j]=0;
For(i,m) {
scanf("%d%d",&a,&b);
f[a][b]=f[b][a]=1;
}
For(i,n) f[i][i]=1;
For(i,n) {
For(j,n) if (f[i][j]) solver::link(i,j);
}
solver::solve();
printf("%d\n",solver::ansd);
}
return 0;
}
HDU 2295 Radar
题目大意:一个国家有n个城市,有m个地方可以建造雷达,最多可以建K个雷达(K>=1 && K<=m),问雷达最短的探测半径,才能使n个城市都能探测到。1 ≤ N, M ≤ 50
重复覆盖+二分,记得搜到k时退出
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int n,m,K,ans;
struct DLX {
#define MAXNode (10000+10)
#define maxn (10000+10)
#define maxm (60)
int L[MAXNode],R[MAXNode],U[MAXNode],D[MAXNode];
int sz,col[maxn],S[maxn],H[maxn];
bool vis[maxm];
void init(int m) {
Rep(i,m+1) {
L[i] = i-1;
R[i] = i+1;
U[i] = D[i] =i;
S[i] = 0;
}
memset(H,-1,sizeof(H));
L[0]=m; R[m] = 0;
sz=m+1;
}
#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 resume(int c) {
int i;
for(int i=U[c];i!=c;i=U[i]) {
L[R[i]] = R[L[i]] = i;
}
}
void link(int r,int c) {
U[sz] = c;
D[sz] = D[c];
U[D[c]] = sz;
D[c] = sz;
if (H[r]==-1) { H[r]=L[sz]=R[sz]=sz; }
else {
L[sz] =H[r];
R[sz] = R[H[r]];
L[R[H[r]]] = sz;
R[H[r]] = sz;
}
S[c]++ ; col[sz++]=c;
}
int A() {
MEM(vis)
int res=0;
FOR(i,R,0) {
if (!vis[i]) {
res++;
vis[i] = 1;
FOR(j,D,i) FOR(k,R,j) {
vis[col[k]]=1;
}
}
}
return res;
}
void dfs(int d) {
if (!R[0]) {
ans=min(ans,d);
} else if (d+A()<min(K+1,ans) ) {
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) resume(j);
resume(i);
}
}
}
}solver;
#define MAXN (60)
double x[MAXN],y[MAXN];
double a[MAXN],b[MAXN];
int main()
{
// freopen("hdu2295.in","r",stdin);
// freopen(".out","w",stdout);
int T=read();
while(T--) {
n=read(); m=read(); K=read();
For(i,n) scanf("%lf%lf",&x[i],&y[i]);
For(i,m) scanf("%lf%lf",&a[i],&b[i]);
double l=0,r=1416,eps=1e-8;
while(r-l>eps) {
double mid=(r+l)/2;
solver.init(n);
For(i,m) For(j,n) if (hypot(a[i]-x[j],b[i]-y[j])<=mid-eps ) {
solver.link(i,j);
}
ans=INF;
solver.dfs(0);
if (ans<=K) r=mid-eps; else l=mid+eps;
}
printf("%.6lf\n",l);
}
return 0;
}
HDU 3529 Bomberman - Just Search!
给一张N*M的矩阵,每个点要么是空的,要么有墙,要么又不可毁灭的障碍。问至少在几个空点设置炸弹,才能炸掉所有墙?一个炸弹能炸到4方向上最近的不为空点的点,所有炸弹同时爆炸,题目保证有解。
(4 <= N, M <= 15)
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int ans=0;
struct DLX {
#define MAXNode (200000+10)
#define maxn (400+10)
#define maxm (400+10)
int L[MAXNode],R[MAXNode],U[MAXNode],D[MAXNode];
int sz,col[maxn],S[maxn],H[maxn];
bool vis[maxm];
void init(int m) {
Rep(i,m+1) {
L[i] = i-1;
R[i] = i+1;
U[i] = D[i] =i;
S[i] = 0;
}
memset(H,-1,sizeof(H));
L[0]=m; R[m] = 0;
sz=m+1;
}
#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 resume(int c) {
int i;
for(int i=U[c];i!=c;i=U[i]) {
L[R[i]] = R[L[i]] = i;
}
}
void link(int r,int c) {
U[sz] = c;
D[sz] = D[c];
U[D[c]] = sz;
D[c] = sz;
if (H[r]==-1) { H[r]=L[sz]=R[sz]=sz; }
else {
L[sz] =H[r];
R[sz] = R[H[r]];
L[R[H[r]]] = sz;
R[H[r]] = sz;
}
S[c]++ ; col[sz++]=c;
}
int A() {
MEM(vis)
int res=0;
FOR(i,R,0) {
if (!vis[i]) {
res++;
vis[i] = 1;
FOR(j,D,i) FOR(k,R,j) {
vis[col[k]]=1;
}
}
}
return res;
}
void dfs(int d) {
if (!R[0]) {
ans=min(ans,d);
} else if (d+A()<ans) {
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) resume(j);
resume(i);
}
}
}
}solver;
int n,m;
#define MAXN (20)
char mat[MAXN][MAXN];
int h[MAXN][MAXN];
int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
int main()
{
// freopen("hdu3529.in","r",stdin);
// freopen(".out","w",stdout);
while(cin>>n>>m) {
Rep(i,n) cin>>mat[i];
int N=0,M=0;
Rep(i,n) Rep(j,m) {
if (mat[i][j]=='.') {
h[i][j]=++N;
}
if (mat[i][j]=='#') {
h[i][j]=++M;
}
}
solver.init(M);
Rep(i,n) Rep(j,m) if (mat[i][j] == '.'){
Rep(d,4) {
int k=1;
while(mat[i+k*dir[d][0]][j+k*dir[d][1]] == '.') ++k;
if (mat[i+k*dir[d][0]][j+k*dir[d][1]]=='#') {
solver.link(h[i][j],h[i+k*dir[d][0]][j+k*dir[d][1]]);
}
}
}
ans=INF;
solver.dfs(0);
cout<<ans<<endl;
}
return 0;
}
HDU 3957 Street Fighter
街霸游戏中,有n(2<=N<=25)种角色,每种角色有1~2种人物,从n种角色中选出哪些角色在那种人物上,可以击败其余的任何角色的任何人物。求选取的最少人物。
同时覆盖X精确覆盖 模板
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case %d: %d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int ans=0;
struct DLX {
#define MAXNode (240000+10)
#define maxn (600+10)
#define maxm (600+10)
int L[MAXNode],R[MAXNode],U[MAXNode],D[MAXNode];
int sz,col[maxn],S[maxn],H[maxn];
int n;
bool vis[maxm];
void init(int m) {
Rep(i,m+1) {
L[i] = i-1;
R[i] = i+1;
U[i] = D[i] =i;
S[i] = 0;
}
memset(H,-1,sizeof(H));
L[0]=m; R[m] = 0;
sz=m+1;
}
#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 resume(int c) {
int i;
for(int i=U[c];i!=c;i=U[i]) {
L[R[i]] = R[L[i]] = i;
}
}
//精确覆盖
void remove1(int c) {
L[R[c]] = L[c];
R[L[c]] = R[c];
FOR(i,D,c)
FOR(j,R,i) {
U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]];
}
}
void resume1(int c) {
FOR(i,U,c)
FOR(j,L,i) {
++S[col[j]];
U[D[j]] = j;
D[U[j]] = j;
}
L[R[c]]=c;
R[L[c]]=c;
}
void link(int r,int c) {
U[sz] = c;
D[sz] = D[c];
U[D[c]] = sz;
D[c] = sz;
if (H[r]==-1) { H[r]=L[sz]=R[sz]=sz; }
else {
L[sz] =H[r];
R[sz] = R[H[r]];
L[R[H[r]]] = sz;
R[H[r]] = sz;
}
S[c]++ ; col[sz++]=c;
}
int A() {
MEM(vis)
int res=0;
FOR(i,R,0) {
if(i>n) break;
if (!vis[i]) {
res++;
vis[i] = 1;
FOR(j,D,i) FOR(k,R,j) {
vis[col[k]]=1;
}
}
}
return res;
}
void dfs(int d) {
if (!R[0]||R[0]>n) {
ans=min(ans,d);
} else if (d+A()<ans) {
int c=R[0];
FOR(i,R,0) {
if(i>n) break;
if (S[i]<S[c]) c=i;
}
FOR(i,D,c) {
remove(i);
FOR(j,R,i) if (col[j]<=n) remove(j);
FOR(j,R,i) if (col[j]>n) remove1(col[j]);
dfs(d+1);
FOR(j,L,i) if (col[j]>n) resume1(col[j]);
FOR(j,L,i) if (col[j]<=n) resume(j);
resume(i);
}
}
}
}solver;
int n,m;
#define MAXN (30)
int main()
{
// freopen("hdu3957.in","r",stdin);
// freopen(".out","w",stdout);
int T=read();
For(kcase,T) {
cin>>n;
solver.init(3*n);
solver.n=2*n;
int t=0;
Rep(i,n) {
cin>>m;
Rep(j,m) {
int u=2*i+j+1;
int k=read();
Rep(l,m) solver.link(u,2*i+l+1);
while(k--) {
int a=read(),b=read();
if (a==i) continue;
int v=a*2+b+1;
solver.link(u,v);
}
solver.link(u,2*n+i+1);
}
if (m==1) solver.link(2*i+2,2*i+2),++t;
}
ans=INF;
solver.dfs(0);
Pr(kcase,ans-t);
}
return 0;
}
HDU 4735 Little Wish~ lyrical step~
题目大意:一棵树上有n<=50个结点,每个结点有一个男生或者一个妹纸,每条边有一个距离,问最少交换多少个人,使得妹纸在距离D内至少有一个男生.
注意这次求的是交换次数,所以要修改跳出条件(需要的男生超过男生总数或交换次数超过当前最优值),由于模板不小心抄错了数组大小对应关系,wa了
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %d\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int ans2=0;
bool b[60];
int boys;
struct DLX {
#define MAXNode (10000+10)
#define maxn (60)
#define maxm (60)
int L[MAXNode],R[MAXNode],U[MAXNode],D[MAXNode];
int sz,col[MAXNode],S[maxn],H[maxn],row[MAXNode];
bool vis[maxm];
void init(int m) {
Rep(i,m+1) {
L[i] = i-1;
R[i] = i+1;
U[i] = D[i] =i;
S[i] = 0;
}
memset(H,-1,sizeof(H));
L[0]=m; R[m] = 0;
sz=m+1;
}
#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 resume(int c) {
int i;
for(int i=U[c];i!=c;i=U[i]) {
L[R[i]] = R[L[i]] = i;
}
}
void link(int r,int c) {
U[sz] = c;
D[sz] = D[c];
U[D[c]] = sz;
D[c] = sz;
if (H[r]==-1) { H[r]=L[sz]=R[sz]=sz; }
else {
L[sz] =H[r];
R[sz] = R[H[r]];
L[R[H[r]]] = sz;
R[H[r]] = sz;
}
S[c]++ ; row[sz]=r; col[sz++]=c;
}
int A() {
MEM(vis)
int res=0;
FOR(i,R,0) {
if (!vis[i]) {
res++;
vis[i] = 1;
FOR(j,D,i) FOR(k,R,j) {
vis[col[k]]=1;
}
}
}
return res;
}
void dfs(int d,int l) {
if (!R[0]) {
ans2=min(ans2,d-l);
} else if (d+A()<boys+1 && d-l < ans2 ) {
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,l+b[row[i]]);
FOR(j,L,i) resume(j);
resume(i);
}
}
}
}solver;
int n,D;
int f[60][60];
void floyd(int n) {
For(k,n) For(i,n) For(j,n) f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
int main()
{
// freopen("hdu4735.in","r",stdin);
// freopen(".out","w",stdout);
int T=read();
For(kcase,T) {
n=read(),D=read();
boys=0;
For(i,n) b[i]=read(),boys+=b[i];
MEMI(f)
For(i,n-1) {
int u=read(),v=read(),w=read();
f[u][v]= f[v][u] = min(f[u][v],w);
}
For(i,n) f[i][i]=0;
floyd(n);
solver.init(n);
For(i,n) For(j,n) if (f[i][j]<=D) solver.link(i,j);
ans2=INF;
solver.dfs(0,0);
Pr(kcase,(ans2==INF)?(-1):(ans2));
}
return 0;
}
HDU 3663 Power Stations
有n个城市,还有m条边(双向),每个城市都有一个发电站,如果一个发电站工作,它能够给它所在的城市和直接相邻的城市提供电力。并且要求每个城市只能由一个发电站来提供电力(即不能够被两个或以上的发电站同时覆盖)。
区间拆成{{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5},
{2, 2}, {2, 3}, {2, 4}, {2, 5},
{3, 3}, {3, 4}, {3, 5},
{4, 4}, {4, 5},
{5, 5}, {0, 0}};
列为第i天第j个city是否取,第i个发电站是否使用
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
struct DLX {
#define maxn (60*16+10)
#define MAXNode (370000+10)
#define maxr (16*60+10)
int n, sz;
int S[maxn];
int row[MAXNode],col[MAXNode];
int L[MAXNode],R[MAXNode],U[MAXNode],D[MAXNode];
int ansd, ans[maxr];
void init(int n) {
this->n = n;
Rep(i,n+1) {
U[i] = D[i] = i ; L[i]=i-1; R[i]=i+1;
}
R[n]=0; L[0]=n;
sz=n+1;
MEM(S)
}
void addRow(int r, vi columns) {
int fir = sz;
int cSz=columns.size();
Rep(i,cSz) {
int c=columns[i];
L[sz] = sz-1; R[sz] = sz+1; D[sz] = c; U[sz] = U[c];
D[ U[c] ] =sz; U[c]=sz;
row[sz] = r; col[sz] = c;
S[c]++; sz++;
}
R[sz-1]=fir; L[fir] = sz-1;
}
#define FOR(i,A,s) for(int i=A[s];i!=s;i=A[i])
void remove(int c) {
L[R[c]] = L[c];
R[L[c]] = R[c];
FOR(i,D,c)
FOR(j,R,i) {
U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]];
}
}
void restore(int c) {
FOR(i,U,c)
FOR(j,L,i) {
++S[col[j]];
U[D[j]] = j;
D[U[j]] = j;
}
L[R[c]]=c;
R[L[c]]=c;
}
//evaluation function
int H() {
int ret=0;
bool vis[maxn];
FOR(i,R,0) {
if (!vis[i]) {
vis[i]=1;
++ret;
FOR(j,D,i)
FOR(k,R,j)
vis[col[k]] = 1;
}
}
return ret;
}
bool dfs(int d) {
if ( R[0] == 0) {
ansd = d;
return 1;
}
int c = R[0];
FOR(i,R,0) if (S[i] < S[c]) c = i;
remove(c);
FOR(i,D,c) {
ans[d] = row[i];
FOR(j,R,i) remove(col[j]);
if (dfs(d+1)) return 1;
FOR(j,L,i) restore(col[j]);
}
restore(c);
return 0;
}
bool solve(vi &v) {
v.clear();
if (!dfs(0)) return 0;
Rep(i,ansd) v.pb(ans[i]);
return 1;
}
};
#define MAXN (60+10)
DLX solver;
int n,m,d;
bool f[MAXN][MAXN];
int l[MAXN],r[MAXN];
int ansl[MAXN],ansr[MAXN];
const int seg[16][2]={{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5},
{2, 2}, {2, 3}, {2, 4}, {2, 5},
{3, 3}, {3, 4}, {3, 5},
{4, 4}, {4, 5},
{5, 5}, {0, 0}};
int main()
{
// freopen("hdu3663.in","r",stdin);
// freopen("hdu3663.out","w",stdout);
while(cin>>n>>m>>d) {
solver.init(n*d+n);
MEM(f)
Rep(i,m) {
int u=read(),v=read();
f[u][v]=f[v][u]=1;
}
For(i,n) {
f[i][i]=1;
cin>>l[i]>>r[i];
}
For(i,n) {
Rep(j,15) {
int u=(i-1)*16+j+1;
vi columns;
if (l[i]<=seg[j][0] && seg[j][1]<=r[i] ) {
For(k,n) {
if (f[i][k])
Fork(l2,seg[j][0],seg[j][1])
{
int v=(k-1)*d+l2;
columns.pb(v);
}
}
columns.pb(n*d+i);
solver.addRow(u,columns);
}
}
vi columns;
columns.pb(n*d+i);
solver.addRow(16*i,columns);
}
vi v;
bool flag=solver.solve(v);
if(!flag) {
puts("No solution"); puts("");continue;
}
int sz=SI(v);
MEM(ansl) MEM(ansr)
Rep(i,sz) {
int u=v[i];
int x=1+(u-1)/16 , y =(u-1)%16;
ansl[x]= seg[y][0];
ansr[x]= seg[y][1];
}
For(i,n) printf("%d %d\n",ansl[i],ansr[i]);
puts("");
}
return 0;
}
FZU 1686 神龙的难题
题目大意:有n*m的01矩阵,1代表有怪物,神龙的攻击范围为n1*m1的矩阵,一次攻击可以把这个范围内的怪物全部消灭,最少攻击几次,把所有的怪物全都灭掉?
#pragma comment(linker, "/STACK:102400000,102400000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int ans=0;
struct DLX {
#define MAXNode (1000000+10)
#define maxn (1000000+10)
#define maxm (1000+10)
int L[MAXNode],R[MAXNode],U[MAXNode],D[MAXNode];
int sz,col[MAXNode],S[maxm],H[maxn];
bool vis[maxm];
void init(int m) {
Rep(i,m+1) {
L[i] = i-1;
R[i] = i+1;
U[i] = D[i] =i;
S[i] = 0;
}
memset(H,-1,sizeof(H));
L[0]=m; R[m] = 0;
sz=m+1;
}
#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 resume(int c) {
int i;
for(int i=U[c];i!=c;i=U[i]) {
L[R[i]] = R[L[i]] = i;
}
}
void link(int r,int c) {
U[sz] = c;
D[sz] = D[c];
U[D[c]] = sz;
D[c] = sz;
if (H[r]==-1) { H[r]=L[sz]=R[sz]=sz; }
else {
L[sz] =H[r];
R[sz] = R[H[r]];
L[R[H[r]]] = sz;
R[H[r]] = sz;
}
S[c]++ ; col[sz++]=c;
}
int A() {
MEM(vis)
int res=0;
FOR(i,R,0) {
if (!vis[i]) {
res++;
vis[i] = 1;
FOR(j,D,i) FOR(k,R,j) {
vis[col[k]]=1;
}
}
}
return res;
}
void dfs(int d) {
if (!R[0]) {
ans=min(ans,d);
} else if (d+A()<ans) {
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) resume(j);
resume(i);
}
}
}
}solver;
#define MAXN (30)
int h[MAXN][MAXN];
int main()
{
// freopen("fzu1686.in","r",stdin);
// freopen(".out","w",stdout);
int n,m;
while(cin>>n>>m) {
int cm=0;
For(i,n) For(j,m) {
int p=read();
if (p==1) h[i][j]=++cm;
else h[i][j]=-1;
}
solver.init(cm);
int n1=read(),m1=read();
For(i,n-n1+1) {
For(j,m-m1+1) {
int u=(i-1)*m+j;
Fork(k,i,i+n1-1)
Fork(l,j,j+m1-1) {
if (h[k][l]!=-1) solver.link(u,h[k][l]);
}
}
}
ans=INF;
solver.dfs(0);
cout<<ans<<endl;
}
return 0;
}
NOIP 2009 靶形数独
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=Pre[x];p;p=Next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,127,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define INF (2139062143)
#define F (100000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
For(j,m-1) cout<<a[i][j]<<' ';\
cout<<a[i][m]<<endl; \
}
#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return (a-b+llabs(a-b)/F*F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
int read()
{
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
const int p[9][9] = {
{6,6,6,6,6,6,6,6,6},
{6,7,7,7,7,7,7,7,6},
{6,7,8,8,8,8,8,7,6},
{6,7,8,9,9,9,8,7,6},
{6,7,8,9,10,9,8,7,6},
{6,7,8,9,9,9,8,7,6},
{6,7,8,8,8,8,8,7,6},
{6,7,7,7,7,7,7,7,6},
{6,6,6,6,6,6,6,6,6}
};
int encode(int a,int b,int c) {
return a*81+b*9+c+1;
}
void decode(int code,int &a,int &b,int &c) {
code--;
c=code%9; code/=9;
b=code%9; code/=9;
a=code;
}
int ans=0;
struct DLX {
#define maxn (10000000+10)
#define MAXNode (10000000+10)
#define maxr (10000000)
int n, sz;
int S[maxn];
int row[MAXNode],col[MAXNode];
int L[MAXNode],R[MAXNode],U[MAXNode],D[MAXNode];
void init(int n) {
this->n = n;
Rep(i,n+1) {
U[i] = D[i] = i ; L[i]=i-1; R[i]=i+1;
}
R[n]=0; L[0]=n;
sz=n+1;
MEM(S)
}
void addRow(int r, vi columns) {
int fir = sz;
int cSz=columns.size();
Rep(i,cSz) {
int c=columns[i];
L[sz] = sz-1; R[sz] = sz+1; D[sz] = c; U[sz] = U[c];
D[ U[c] ] =sz; U[c]=sz;
row[sz] = r; col[sz] = c;
S[c]++; sz++;
}
R[sz-1]=fir; L[fir] = sz-1;
}
#define FOR(i,A,s) for(int i=A[s];i!=s;i=A[i])
void remove(int c) {
L[R[c]] = L[c];
R[L[c]] = R[c];
FOR(i,D,c)
FOR(j,R,i) {
U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]];
}
}
void restore(int c) {
FOR(i,U,c)
FOR(j,L,i) {
++S[col[j]];
U[D[j]] = j;
D[U[j]] = j;
}
L[R[c]]=c;
R[L[c]]=c;
}
void dfs(int d,int l) {
if ( R[0] == 0) {
ans = max(ans,l);return;
}
int c = R[0];
FOR(i,R,0) if (S[i] < S[c]) c = i;
remove(c);
FOR(i,D,c) {
FOR(j,R,i) remove(col[j]);
int rr,cc,vv;
decode(row[i],rr,cc,vv);
dfs(d+1,l+(1+vv)*p[rr][cc] );
FOR(j,L,i) restore(col[j]);
}
restore(c);
}
void solve() {
dfs(0,0);
}
};
DLX solver;
int puzzle[9][9];
void init() {
Rep(i,9) {
Rep(j,9) cin>>puzzle[i][j];
}
}
const int SLOT = 0;
const int ROW = 1;
const int COL = 2;
const int SUB = 3;
int main()
{
// freopen("vijosP1755.in","r",stdin);
// freopen(".out","w",stdout);
init();
solver.init(81*4); //列数要初始化
Rep(r,9) Rep(c,9) Rep(v,9) { // put v in (r,c)
if (puzzle[r][c]==0||puzzle[r][c]==1+v) {
vi columns;
columns.pb(encode(SLOT,r,c));
columns.pb(encode(ROW,r,v));
columns.pb(encode(COL,c,v));
columns.pb(encode(SUB,r/3*3+c/3,v));
solver.addRow(encode(r,c,v),columns);
}
}
ans=0;
solver.solve();
if (!ans) puts("-1");
else cout<<ans<<endl;
return 0;
}