• 【HEOI2016/TJOI2016】游戏


    题面

    https://www.luogu.org/problemnew/show/P2825

    题解

    水题

    二分图匹配的经典模型。

    对于硬石头,拆点。

    // luogu-judger-enable-o2
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<queue>
    #define ri register int
    #define N 505000
    #define INF 1000000007
    #define T (n+m+1)
    
    using namespace std;
    
    int n,m,han[100][100],lie[100][100];
    vector<int> to,w,ed[N];
    int cur[N],d[N],tn,tm;
    char g[100][100];
    
    void add_edge(int u,int v,int w1,int w2) {
      to.push_back(v); w.push_back(w1); ed[u].push_back(to.size()-1);
      to.push_back(u); w.push_back(w2); ed[v].push_back(to.size()-1);
    }
    
    bool bfs() {
      queue<int> q;
      memset(d,0x3f,sizeof(d));
      d[0]=0; q.push(0);
      while (!q.empty()) {
        int x=q.front(); q.pop();
        for (ri i=0,l=ed[x].size();i<l;i++) {
          int e=ed[x][i];
          if (w[e] && d[x]+1<d[to[e]]) {
            d[to[e]]=d[x]+1;
            q.push(to[e]);
          }
        }
      }
      return d[T]<=1000000;
    }
    
    int dfs(int x,int limit) {
      if (x==T || !limit) return limit;
      int tot=0;
      for (ri &i=cur[x];i<ed[x].size();i++) {
        int e=ed[x][i];
        if (d[to[e]]==d[x]+1 && w[e]) {
          int f=dfs(to[e],min(limit,w[e]));
          if (!f) continue;
          w[e]-=f; w[1^e]+=f; 
          tot+=f; limit-=f;
          if (!limit) return tot;
        }
      }
      return tot;
    }
    
    int dinic() {
      int ret=0;
      while (bfs()) {
        memset(cur,0,sizeof(cur));
        ret+=dfs(0,INF);
      }
      return ret;
    }
    
    void init() {
        int tn=0,tm=0;
      for (ri i=1;i<=n;i++) {
        ++tn;
        for (ri j=1;j<=m;j++) {
            han[i][j]=tn;
            if (g[i][j]=='#') tn++;
          }
        }
        for (ri i=1;i<=m;i++) {
          ++tm;
          for (ri j=1;j<=n;j++) {
            lie[j][i]=tm;
            if (g[j][i]=='#') tm++;
          }
        }
        n=tn; m=tm;
        return;
    }
    
    void makegraph() {
      for (ri i=1;i<=n;i++) add_edge(0,i,1,0);
      for (ri i=1;i<=m;i++) add_edge(n+i,T,1,0);
      for (ri i=1;i<=tn;i++)
        for (ri j=1;j<=tm;j++) if (g[i][j]=='*') add_edge(han[i][j],n+lie[i][j],1,0);
    }
    
    int main() {
      scanf("%d %d",&n,&m); tn=n; tm=m;
      for (ri i=1;i<=n;i++) scanf("%s",g[i]+1);
      init();
      makegraph();
      printf("%d
    ",dinic());
    }
  • 相关阅读:
    linux系统判断内存是否达到瓶颈的小技巧
    利用tcpdump命令统计http的GET和POST请求
    tcpdump 基于mac地址抓取数据包
    使用liunx系统自带的工具sar监控指定接口速率
    Windows 环境搭建Redis集群
    Windows下RabbitMQ安装,部署,配置
    鼠标事件(二)
    鼠标事件(一)
    响应式web之媒体查询(一)
    UI事件之unload、resize和scroll
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11104967.html
Copyright © 2020-2023  润新知