P2172 [National Team] tribal wars maximum flow

  

Title Description

A lanzerb tribes in the upper part of the country, they are dissatisfied with the cold environment, so ready to go on an expedition to the lower part of country A to get more territory.

A country is a M * N matrix, where some local cities and towns, some places are uninhabited mountain ravine. lanzerb his own tribe is divided into several armies, they agreed to:

  1. Every army can start from any town, and can only go down from the campaign, not go back. Only through town on his way, not through the mountain ravine.

  2. If a town had to be an army, the military can not go to that other towns of.

  3. Every army can stop a campaign at any town.

  4. All the troops were surprised, the way they walk a bit like chess horse. But Ma can only take Route 1 * 2, and they can only take the route R * C.

lanzerb ambition makes his goal is to unify the country, but the limit of troops makes them powerless when Manning. Assuming they can successfully Every army occupied all the towns through which the army, at least you please help lanzerb calculate how many armies in order to complete the great task of reunifying the country.

Input and output formats

Input formats:

 

The first row contains four integers M, N, R, C, see the problem described meaning. Next M lines each a string of length N. If a character that represents this place is the town ''; if when the character 'x', indicates that this place is a mountain ravine.

 

Output formats:

 

Output an integer, represents the minimum number of forces.

 

Sample input and output

Input Sample # 1:  Copy
3 3 1 2
...
.x.
...
Output Sample # 1:  Copy
4
Input Sample # 2:  Copy
5 4 1 1
....
..x.
...x
....
x...
Output Sample # 2:  Copy
5 


covering template mention is the smallest maximum flow path
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
const int N=1e6;
const int M=4e6+54;

struct edge {
    int to, next, w;
} e[M << 1];
int head[N], cnt = 1;
void add(int x, int y, int z) {
    e[++cnt] = (edge){y, head[x], z};
    head[x] = cnt;
    e[++cnt] = (edge){x, head[y], 0};
    head[y] = cnt;
}
int level[N];
bool bfs(int s, int t) {
    memset(level, 0, sizeof level);
    queue<int> q;
    level[s] = 1;
    q.push(s);
    while (!q.empty()) {
        int pos = q.front();
        q.pop();
        for (int i = head[pos]; i; i = e[i].next) {
            int nx = e[i].to;
            if (!e[i].w || level[nx]) continue;
            level[nx] = level[pos] + 1;
            q.push(nx);
        }
    }
    return level[t];
}
int dfs(int s, int t, int flow) {
    if (s == t) return flow;
    int ret = 0;
    for (int i = head[s]; flow && i; i = e[i].next) {
        int nx = e[i].to;
        if (level[nx] == level[s] + 1 && e[i].w) {
            int tmp = dfs(nx, t, min(flow, e[i].w));
            e[i].w -= tmp;
            e[i ^ 1].w += tmp;
            flow -= tmp;
            ret += tmp;
        }
    }
    if (!ret) level[s] = 0;
    return ret;
}
int dinic(int s, int t) {
    int ret = 0;
    while (bfs(s, t)) ret += dfs(s, t, inf);
    return ret;
}
int n,m,s,t,a,b,c,r ;
int dx[4],dy[4];
char mp[300][300];

int id(int x,int y)
{
    return x*m+y;
}

int main()
{
    cin>>n>>m>>r>>c;
    dy[0]=-r;dx[0]=c;
    dy[1]= r;dx[1]=c;
    dy[2]= c;dx[2]=r;
    dy[3]=-c;dx[3]=r;
    rep(i,1,n)RS(mp[i]+1);
    int sum=0;

    s=n*m*10+1,t=s+1;
    int T=n*m+m+n;

    rep(i,1,n)
    rep(j,1,m)
    {
        if(mp[i][j]=='.')
        {
            add(s,id(i,j),1);
            add(id(i,j)+T,t,1);sum++;
            rep(k,0,3)
            {
                int x=i+dx[k],y=j+dy[k];
                if( x>n||x<1||y<1||y>m)continue;
                if(mp[x][y]!='.')continue;
                add(id(i,j),id(x,y)+T,1);
            }
        }
    }
   // printf("okok");
    cout<<sum-dinic(s,t);

    return 0;
}
View Code

 



Guess you like

Origin www.cnblogs.com/bxd123/p/11233870.html