zoukankan      html  css  js  c++  java
  • P4311 士兵占领 (网络流)

    题目链接

    解法:

    首先考虑逆向思维,求最少要使用的士兵个数,转化为,初始的时候所有能放士兵的地方都放了士兵的情况下,最多能删掉多少个士兵。

    1. 给每一行每一列分别建一个点,对于所有非障碍坐标(x,y),从x行对应的点 向 y列对应的点连一条容量为1的边,表示这个位置的士兵最多可以删除一次。

    2. 源点向每一行对应的点连边,容量为这一行能删除的士兵个数的最大值(即 列数m - 这一行的障碍数 - 这一行需要的士兵数L[i])。

    3. 每一列对应的点向汇点连边,容量为这一列能删除的士兵个数的最大值(即 行数n - 这一列的障碍数 - 这一列需要的士兵数C[i])。

    这样跑一个最大流,每一个单位的流量表示删除一个士兵,不难证明 任意一种流量状态都与一种合法的士兵删除方案相对应。

    特判无解的情况,如果所有能放士兵的地方都放上了士兵,仍然存在行或列不满足限制条件,输出无解即可。

    copy from: https://www.luogu.com.cn/blog/user36456/solution-p4311 

    Code:

      1 #include <bits/stdc++.h>
      2 #define LL long long
      3 #define INF 0x3f3f3f3f;
      4 using namespace std;
      5 
      6 int M, N, K;
      7 int row[110], col[110];
      8 int grid[110][110];
      9 int S, T;
     10 int maxsub;
     11 struct Edge{
     12     int next, from, to, remain;
     13 }e[25000];
     14 int en;
     15 int head[300];
     16 queue<int> q;
     17 int visited[300];
     18 int preEdge[300];
     19 int minflow[300];
     20 
     21 void addEdge(int from, int to, int flow){
     22     e[en].next=head[from];
     23     e[en].from=from;
     24     e[en].to=to;
     25     e[en].remain=flow;
     26     head[from]=en;
     27     ++en;
     28 }
     29 
     30 void add(int from, int to, int flow){
     31     addEdge(from, to, flow);
     32     addEdge(to, from, 0);
     33 }
     34 
     35 void bfs(){
     36     memset(visited,0,sizeof(visited));
     37     memset(preEdge,-1,sizeof(preEdge));
     38     memset(minflow,0,sizeof(minflow));
     39     q.push(S);
     40     visited[S]=1;
     41     minflow[S]=INF;
     42     while(!q.empty()){
     43         int u=q.front();
     44         q.pop();
     45         for(int i=head[u];i!=-1;i=e[i].next){
     46             if(e[i].remain>0 && !visited[e[i].to]){
     47                 visited[e[i].to]=1;
     48                 minflow[e[i].to]=min(minflow[u],e[i].remain);
     49                 preEdge[e[i].to]=i;
     50                 q.push(e[i].to);
     51             }
     52         }
     53     }
     54 }
     55 
     56 void EK(){
     57     while(true){
     58         bfs();
     59         if(preEdge[T]==-1) break;
     60         maxsub+=minflow[T];
     61         int v=T;
     62         while(true){
     63             int edge=preEdge[v];
     64             if(edge==-1) break;
     65             e[edge].remain-=minflow[T];
     66             e[edge^1].remain+=minflow[T];
     67             v=e[edge].from;
     68         }
     69     }
     70 }
     71 
     72 int main(){
     73     memset(head,-1,sizeof(head));
     74     scanf("%d %d %d", &M, &N, &K);
     75     for(int i=1;i<=M;++i){
     76         scanf("%d", row+i);
     77     }
     78     for(int i=1;i<=N;++i){
     79         scanf("%d", col+i);
     80     }
     81     for(int i=1;i<=K;++i){
     82         int x,y;
     83         scanf("%d %d", &x, &y);
     84         grid[x][y]=1;
     85     }
     86     S=0;
     87     T=M+N+1;
     88     for(int i=1;i<=M;++i){
     89         int blocks=0;
     90         for(int j=1;j<=N;++j){
     91             if(grid[i][j]){
     92                 blocks++;
     93             }else{
     94                 add(i,j,1);
     95             }
     96         }
     97         if(N-blocks-row[i]<0) {
     98             printf("JIONG!");
     99             return 0;
    100         }
    101         add(S,i,N-blocks-row[i]);
    102     }
    103 
    104     for(int j=1;j<=N;++j){
    105         int blocks=0;
    106         for(int i=1;i<=M;++i){
    107             if(grid[i][j]) blocks++;
    108         }
    109         if(M-blocks-col[j]<0){
    110             printf("JIONG!");
    111             return 0;
    112         }
    113         add(j,T,M-blocks-col[j]);
    114     }
    115 
    116     EK();
    117     int res=M*N-K-maxsub;
    118     printf("%d", res);
    119     return 0;
    120 }
  • 相关阅读:
    浅析跨域请求
    python虚拟环境--virtualenv
    centos7下使用yum安装pip
    centos下python安装与虚拟环境配置
    ES6基础语法
    CCI_chapter 19 Moderate
    CCI_chapter 16 Low level
    CCI_chapter 13C++
    CCI_chapter 8 Recurision
    LeetCode_Generate Parentheses
  • 原文地址:https://www.cnblogs.com/FEIIEF/p/12245728.html
Copyright © 2011-2022 走看看