zoukankan      html  css  js  c++  java
  • HDU 1045 Fire Net(行列匹配变形+缩点建图)

    题意:n*n的棋盘上放置房子。同一方同一列不能有两个,除非他们之间被墙隔开,这种话。
    把原始图分别按行和列缩点
    建图:横竖分区。先看每一列。同一列相连的空地同一时候看成一个点,显然这种区域不可以同一时候放两个点。

    这些点作为二分图的X部。同理在对全部的 行用同样的方法缩点。作为Y部。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<set>
    #include<map>
    #include<string>
    #include<cstring>
    #include<stack>
    #include<queue>
    #include<vector>
    #include<cstdlib>
    #define lson (rt<<1),L,M
    #define rson (rt<<1|1),M+1,R
    #define M ((L+R)>>1)
    #define cl(a,b) memset(a,b,sizeof(a));
    #define LL long long
    #define P pair<int,int>
    #define X first
    #define Y second
    #define pb push_back
    #define fread(zcc)  freopen(zcc,"r",stdin)
    #define fwrite(zcc) freopen(zcc,"w",stdout)
    using namespace std;
    const int maxn=505;
    const int inf=999999;
    
    vector<int> G[maxn];
    int matching[maxn];
    bool vis[maxn];
    int num;
    bool dfs(int u){
        int N=G[u].size();
        for(int i=0;i<N;i++){
            int v=G[u][i];
            if(vis[v])continue;
            vis[v]=true;
            if(matching[v]==-1||dfs(matching[v])){
                matching[v]=u;
                return true;
            }
        }
        return false;
    }
    int hungar(){
        int ans=0;
        cl(matching,-1);
        for(int i=0;i<num;i++){
            cl(vis,false);
            if(dfs(i))ans++;
        }
        return ans;
    }
    char a[maxn][maxn];
    int row[maxn][maxn];
    int col[maxn][maxn];
    int main(){
      //  fread("Text/in.txt");
        int n;
        while(scanf("%d",&n)&&n){
            for(int i=0;i<n;i++){
                scanf("%s",a[i]);
            }
            cl(row,-1);
            cl(col,-1);
            int cnt=0,cnt2=0;
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    if(a[i][j]=='.'){
                        int k=j;
                        bool ok=false;//依照行缩点,进行编号
                        while(k<n&&a[i][k]=='.'&&row[i][k]==-1){
                            row[i][k]=cnt;k++;ok=true;
                        }
                        if(ok)cnt++;
                        k=i;
                        ok=false;//依照列编号
                        while(i<n&&a[k][j]=='.'&&col[k][j]==-1){
                            col[k][j]=cnt2;k++;ok=true;
                        }
                        if(ok)cnt2++;
                    }
                }
            }
            num++;
            for(int i=0;i<n;i++){
                for(int j=0;j<n;j++){
                    if(a[i][j]=='.'){
                        G[row[i][j]].pb(col[i][j]);
                        num++;
                    }
                }
            }
            printf("%d
    ",hungar());
            for(int i=0;i<maxn;i++)G[i].clear();
        }
        return 0;
    }
    
  • 相关阅读:
    以中间件,路由,跨进程事件的姿势使用WebSocket
    傻瓜式解读koa中间件处理模块koa-compose
    企业管理系统前后端分离架构设计 系列一 权限模型篇
    vue权限路由实现方式总结
    3YAdmin-专注通用权限控制与表单的后台管理系统模板
    lazy-mock ,一个生成后端模拟数据的懒人工具
    vue-quasar-admin 一个包含通用权限控制的后台管理系统
    CSS中line-height与vertical-align
    IdentityServer4实现Token认证登录以及权限控制
    利用AOP实现SqlSugar自动事务
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7191059.html
Copyright © 2011-2022 走看看