The minimal path overlay problem is that given a DAG, a path overlay for that Dag is a collection of paths, so that each point belongs to and belongs to only one of the paths, and the problem is to find a collection of paths of the smallest size.
The practice is to split each point a into two points a1,a2, if a->b, then even a1->b2 to ask for a maximum match.
One conclusion is: Minimum number of paths = points-Maximum match
The approximate idea of proving is:
A path overlay corresponds to an edge independent set (that is, a match) of one by one.
Number of paths covered by one path = number of points-matches (because the number of paths + the number of edges per path and -1 = n points of the non-connected non-circular graph edge number, matching number equals the number of edges per path and)
1 /**************************************************************2 problem:21503 user:idy0024 language:c++5 result:accepted6 time:52 Ms7 memory:1652 KB8 ****************************************************************/9 Ten#include <cstdio> One#include <cstring> A#include <vector> - #defineN 55 - #defineS n*n*2 the #defineOO 0x3f3f3f3f - using namespacestd; - - structEdge { + intu, V, F; -Edge (intUintVintf): U (U), V (v), F (f) {} + }; A at intN, M, R, C, CNT; - CharBoard[n][n]; - intidx[2][n][n], SRC, DST, IDC; - intdx[4], dy[4]; - -Vector<edge>Edge; invector<int>G[s]; - intDep[s], Cur[s], qu[s], BG, ed; to + voidMakeid () { -IDC =0; thesrc = + +IDC; * for(intI=1; i<=n; i++ ) $ for(intj=1; j<=m; J + + )Panax Notoginseng for(intC=0; c<2; C++ ) -IDX[C][I][J] = + +IDC; theDST = + +IDC; + } A voidAdde (intUintVintf) { the G[u].push_back (Edge.size ()); + Edge.push_back (Edge (u,v,f)); - G[v].push_back (Edge.size ()); $Edge.push_back (Edge (V,u,0) ); $ } - voidbuild () { - for(intI=1; i<=n; i++ ) the for(intj=1; j<=m; J + + ) { - if(board[i][j]!='.')Continue;WuyiAdde (SRC, idx[0][I][J],1 ); theAdde (idx[1][I][J], DST,1 ); - } Wu for(intI=1; i<=n; i++ ) - for(intj=1; j<=m; J + + ) { About if(board[i][j]!='.')Continue; $ intU = idx[0][i][j]; - for(intD=0; d<4; d++ ) { - intNI = i+Dx[d]; - intNJ = j+Dy[d]; A if(1<=ni&&ni<=n &&1<=nj&&nj<=m && board[i][j]=='.' ) { + intv = idx[1][ni][nj]; theAdde (U, V,1 ); - } $ } the } the } the BOOLBFs () { thememset (DEP,0,sizeof(DEP)); -Qu[bg=ed=1] =src; inDEP[SRC] =1; the while(bg<=ed) { the intu=qu[bg++]; About for(intt=0; T<g[u].size (); t++ ) { theEdge &e =Edge[g[u][t]]; the if(E.F &&!)DEP[E.V]) { theDEP[E.V] = dep[e.u]+1; +Qu[++ed] =e.v; - } the }Bayi } the returnDEP[DST]; the } - intDfsintUinta) { - if(U==DST | | a==0)returnA; the intRemain=a, past=0, na; the for(int&t=cur[u]; T<g[u].size (); t++ ) { theEdge &e=Edge[g[u][t]]; theEdge &ve=edge[g[u][t]^1]; - if(E.f && dep[e.v]==dep[e.u]+1&& (na=Dfs (E.v,min (REMAIN,E.F)))) { theRemain-=na; thePast + =na; theE.F-=na;94Ve.f + =na; the if(!remain) Break; the } the }98 returnpast; About } - intMaxflow () {101 intFlow =0;102 while(BFS ()) {103memset (cur,0,sizeof(cur));104Flow + =DFS (src,oo); the }106 returnflow;107 }108 intMain () {109scanf"%d%d%d%d", &n, &m, &r, &c); thedx[0]=r, dy[0]=c, dx[1]=r, dy[1]=-C;111dx[2]=c, dy[2]=r, dx[3]=c, dy[3]=-R; the for(intI=1; i<=n; i++ ) {113scanf"%s", board[i]+1 ); the for(intj=1; BOARD[I][J]; J + + ) the if(board[i][j]=='.') cnt++; the }117 Makeid ();118 build ();119printf"%d\n", cnt-Maxflow ()); -}
View Code
Bzoj 2150 Minimum Path overlay