Bare minimum path overlay.
Split each point into a two-part graph.
For point pairs that can be connected (i,j): I->j ' (1);
For any point I, if I point is '. ': S->i (1), I '->t (1);
The answer is all '. ' Number-Maximum stream (maximum number of matches).
Citation proof:
Each simple path in the path overlay has a unique successor in addition to the last vertex, so that the number of matched edges is the node number that is not the end of the path, so that when the number of matched edges reaches the maximum, the node with the least path end is the largest, so the path ends with the fewest nodes.
#include <cstdio> #include <cstring> #include <algorithm> #include <queue>using namespace std;# Define INF 2147483647#define maxn 5011#define maxm 5000301int v[maxm],cap[maxm],en,first[maxn],next[maxm];int D[MAXN], Cur[maxn];queue<int>q;int n,m,s,t,n,m,r,c;void init_dinic () {memset (first,-1,sizeof (first)); en=0; N=N*M; s=0; t=n*m+1;} void Addedge (const int &U,CONST int &v,const int &w) {v[en]=v; cap[en]=w; next[en]=first[u]; first[u]=en++;v[ En]=u; NEXT[EN]=FIRST[V]; first[v]=en++;} BOOL BFs () {memset (d,-1,sizeof (d)); Q.push (S); d[s]=0; while (!q.empty ()) {int U=q.front (); Q.pop (); for (int i=first[u];i!=-1;i=next[i]) if (d[v[i]]==-1 && cap[i]) {d[v[i]]=d[u]+1; Q.push (V[i]); }} return d[t]!=-1;} int dfs (int u,int a) {if (u==t | |!a) return A; int flow=0,f; for (int &i=cur[u];i!=-1;i=next[i]) if (D[u]+1==d[v[i]] && (F=dfs (V[i],min (a,cap[i)))) {cap[i]-=f; cap[i^1]+=f; Flow+=f; A-=f; if (!a) break; } if (! Flow) D[u]=-1; return Flow;} int Max_flow () {int flow=0,tmp=0; while (BFS ()) {memcpy (Cur,first, ((n<<1) +5) *sizeof (int)); while (Tmp=dfs (S,inf)) flow+=tmp; } return Flow;} Char map[52][52];int num[52][52],sumv;bool Check (int x1,int y1,int x2,int y2) {if (x2<=n && x2>=1 &&am P Y2<=m && y2>=1 && map[x2][y2]== '. ') Addedge (num[x1][y1],num[x2][y2]+n,1);} int main () {scanf ("%d%d%d%d", &n,&m,&r,&c), Init_dinic (); for (int i=1;i<=n;++i) scanf ("%s", map[i]+ 1); for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) num[i][j]=++en;init_dinic (), for (Int. i=1;i<=n;++i) for (int j=1 ; j<=m;++j) if (map[i][j]== '. ') {++SUMV; Addedge (s,num[i][j],1); Addedge (num[i][j]+n,t,1); Check (I,J,I+R,J+C); Check (I,J,I+R,J-C); if (r!=c) {check (I,J,I+C,J+R);Check (I,J,I+C,J-R); }}printf ("%d\n", Sumv-max_flow ()); return 0;}
"Minimum path override" "Dichotomy" "Max Flow" "Dinic" bzoj2150 Tribal Wars