BZOJ 2150: 部落战争 最大流
2150: 部落战争
Time Limit: 1 Sec
Memory Limit: 256 MB
题目连接
http://www.lydsy.com/JudgeOnline/problem.php?id=2150Description
lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国的下部征战来获得更大的领土。 A国是一个M*N的矩阵,其中某些地方是城镇,某些地方是高山深涧无人居住。lanzerb把自己的部落分成若干支军队,他们约定: 1. 每支军队可以从任意一个城镇出发,并只能从上往向下征战,不能回头。途中只能经过城镇,不能经过高山深涧。 2. 如果某个城镇被某支军队到过,则其他军队不能再去那个城镇了。 3. 每支军队都可以在任意一个城镇停止征战。 4. 所有军队都很奇怪,他们走的方法有点像国际象棋中的马。不过马每次只能走1*2的路线,而他们只能走R*C的路线。 lanzerb的野心使得他的目标是统一全国,但是兵力的限制使得他们在配备人手时力不从心。假设他们每支军队都能顺利占领这支军队经过的所有城镇,请你帮lanzerb算算至少要多少支军队才能完成统一全国的大业。
Input
第一行包含4个整数M、N、R、C,意义见问题描述。接下来M行每行一个长度为N的字符串。如果某个字符是'.',表示这个地方是城镇;如果这个字符时'x',表示这个地方是高山深涧。
Output
输出一个整数,表示最少的军队个数。
Sample Input
3 3 1 2
...
.x.
...
Sample Output
4
HINT
题意
题解:
最小路径覆盖问题
用总数减去最大流就好了
代码:
//qscqesze #include <cstdio> #include <cmath> #include <cstring> #include <ctime> #include <iostream> #include <algorithm> #include <set> #include <bitset> #include <vector> #include <sstream> #include <queue> #include <typeinfo> #include <fstream> #include <map> #include <stack> typedef long long ll; using namespace std; //freopen("D.in","r",stdin); //freopen("D.out","w",stdout); #define sspeed ios_base::sync_with_stdio(0);cin.tie(0) #define maxn 200500 #define mod 1001 #define eps 1e-9 #define pi 3.1415926 int Num; //const int inf=0x7fffffff; const ll inf=999999999; inline ll read() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } //************************************************************************************* namespace NetFlow { const int MAXN=100000,MAXM=100000,inf=1e9; struct Edge { int v,c,f,nx; Edge() {} Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {} } E[MAXM]; int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],N,sz; void init(int _n) { N=_n,sz=0; memset(G,-1,sizeof(G[0])*N); } void link(int u,int v,int c) { E[sz]=Edge(v,c,0,G[u]); G[u]=sz++; E[sz]=Edge(u,0,0,G[v]); G[v]=sz++; } int ISAP(int S,int T) {//S -> T int maxflow=0,aug=inf,flag=false,u,v; for (int i=0;i<N;++i)cur[i]=G[i],gap[i]=dis[i]=0; for (gap[S]=N,u=pre[S]=S;dis[S]<N;flag=false) { for (int &it=cur[u];~it;it=E[it].nx) { if (E[it].c>E[it].f&&dis[u]==dis[v=E[it].v]+1) { if (aug>E[it].c-E[it].f) aug=E[it].c-E[it].f; pre[v]=u,u=v; flag=true; if (u==T) { for (maxflow+=aug;u!=S;) { E[cur[u=pre[u]]].f+=aug; E[cur[u]^1].f-=aug; } aug=inf; } break; } } if (flag) continue; int mx=N; for (int it=G[u];~it;it=E[it].nx) { if (E[it].c>E[it].f&&dis[E[it].v]<mx) { mx=dis[E[it].v]; cur[u]=it; } } if ((--gap[dis[u]])==0) break; ++gap[dis[u]=mx+1]; u=pre[u]; } return maxflow; } bool bfs(int S,int T) { static int Q[MAXN]; memset(dis,-1,sizeof(dis[0])*N); dis[S]=0; Q[0]=S; for (int h=0,t=1,u,v,it;h<t;++h) { for (u=Q[h],it=G[u];~it;it=E[it].nx) { if (dis[v=E[it].v]==-1&&E[it].c>E[it].f) { dis[v]=dis[u]+1; Q[t++]=v; } } } return dis[T]!=-1; } int dfs(int u,int T,int low) { if (u==T) return low; int ret=0,tmp,v; for (int &it=cur[u];~it&&ret<low;it=E[it].nx) { if (dis[v=E[it].v]==dis[u]+1&&E[it].c>E[it].f) { if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f))) { ret+=tmp; E[it].f+=tmp; E[it^1].f-=tmp; } } } if (!ret) dis[u]=-1; return ret; } int dinic(int S,int T) { int maxflow=0,tmp; while (bfs(S,T)) { memcpy(cur,G,sizeof(G[0])*N); while (tmp=dfs(S,T,inf)) maxflow+=tmp; } return maxflow; } } using namespace NetFlow; string s[100]; int M[52][52][3]; int tot=1; int get_id(int x,int y,int z) { if(M[x][y][z])return M[x][y][z]; else return M[x][y][z]=tot++; } int n,m,r,c; int judge(int x,int y) { if(x>=n||x<0)return 0; if(y>=m||y<0)return 0; if(s[x][y]=='.') return 1; return 0; } int main() { init(100000); n=read(),m=read(),c=read(),r=read(); for(int i=0;i<n;i++) cin>>s[i]; int ans = 0; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(s[i][j]=='.') { ans++; link(get_id(0,0,0),get_id(i,j,1),1); link(get_id(i,j,2),get_id(1,0,0),1); int x,y; x=i+r;y=j+c; if(judge(x,y))link(get_id(i,j,1),get_id(x,y,2),1); x=i+r;y=j-c; if(judge(x,y))link(get_id(i,j,1),get_id(x,y,2),1); x=i+c;y=j+r; if(judge(x,y))link(get_id(i,j,1),get_id(x,y,2),1); x=i+c;y=j-r; if(judge(x,y))link(get_id(i,j,1),get_id(x,y,2),1); } } } int K = dinic(get_id(0,0,0),get_id(1,0,0)); printf("%d\n",ans - K); }