部落战争
刚看完题以为挺难的题..没想到一点开题解,哇.....
好吧,其实简化一下题意答案就出来了.一个军队会走若干个城镇,每个城镇只能被一个军队占领.要求将所有的城镇都占领的最小代价.
每个军队不就是相当于一条路径吗?其实就是选出最少的路径覆盖整个图.那不就是最小路径点覆盖....
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=51; int n,m,c,r,link[N*N*2],tot,match[N*N*2],dx[4],dy[4],cnt,vis[N*N*2],ans; char ch[N][N]; struct edge{int y,next;}a[N*N*N*N]; inline int read() { int x=0,ff=1; char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();} while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*ff; } inline void add(int x,int y) { a[++tot].y=y; a[tot].next=link[x]; link[x]=tot; } inline bool dfs(int x) { for(int i=link[x];i;i=a[i].next) { int y=a[i].y; if(!vis[y]) { vis[y]=1; if(!match[y]||dfs(match[y])) {match[y]=x;return true;} } } return false; } int main() { freopen("1.in","r",stdin); n=read();m=read();c=read();r=read(); for(int i=1;i<=n;++i) scanf("%s",ch[i]+1); dx[0]=r;dx[1]=c;dx[2]=c;dx[3]=r; dy[0]=-c;dy[1]=-r;dy[2]=r;dy[3]=c; for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) if(ch[i][j]=='.') { for(int k=0;k<4;++k) { int x=i+dx[k],y=j+dy[k]; if(x>=1&&x<=n&&y>=1&&y<=m&&ch[x][y]=='.') add((i-1)*m+j,(x-1)*m+y+n*m); } ++cnt; } for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { if(ch[i][j]=='.') { memset(vis,0,sizeof(vis)); if(dfs((i-1)*m+j)) ++ans; } } printf("%d",cnt-ans); return 0; }
来源:https://www.cnblogs.com/gcfer/p/12561425.html