zoukankan      html  css  js  c++  java
  • LC 1349. Maximum Students Taking Exam (Hungarian / Max Flow)

    Link

     Solution 1 Hungarian:

    class Solution {
    public:
        int m,n;
        vector<vector<int>> g;
        vector<vector<int>> dir={{0,-1},{-1,-1},{1,-1},{0,1},{-1,1},{1,1}};
        int maxStudents(vector<vector<char>>& seats) {
            m=seats.size();
            n=seats[0].size();
            g=vector<vector<int>>(m*n,vector<int>(m*n,0));
            int seatcnt=0;
            for(int i=0;i<m;++i){
                for(int j=0;j<n;++j){
                    if(seats[i][j]=='#') continue;
                    seatcnt++;
                    if(j%2==0){
                        for(int d=0;d<6;++d){
                            int ni=i+dir[d][0];
                            int nj=j+dir[d][1];
                            if(ni<0 || ni>=m || nj<0 || nj>=n || seats[ni][nj]=='#') continue;
                            g[i*n+j][ni*n+nj]=1;
                        }
                    }
                }
            }
            vector<int> mat(m*n,-1);
            int cnt=0;
            for(int i=0;i<m;++i){
                for(int j=0;j<n;++j){
                    if(j%2==0 && seats[i][j]=='.'){
                        vector<int> visited(m*n,0);
                        if(dfs(i*n+j,mat,visited)){
                            cnt++;
                        }
                    }
                }
            }
            return seatcnt-cnt;
        }
        
        bool dfs(int u, vector<int> &mat, vector<int> &visited){
            for(int i=0;i<m*n;++i){
                if(g[u][i]==1){
                    if(visited[i]==1) continue;
                    visited[i]=1;
                    if(mat[i]==-1 || dfs(mat[i],mat,visited)){
                        mat[i]=u;
                        return true;
                    }
                }
            }
            return false;
        }
        
    };

    Solution 2 Max Flow:

    class Solution {
    public:
        int m,n;
        vector<vector<int>> g;
        vector<vector<int>> dir={{0,-1},{-1,-1},{1,-1},{0,1},{-1,1},{1,1}};
        int S,T;
        int flow;
        int maxStudents(vector<vector<char>>& seats) {
            m=seats.size();
            n=seats[0].size();
            S=m*n;
            T=m*n+1;
            g=vector<vector<int>>(m*n+2,vector<int>(m*n+2,0));  // residual capacity 
            int seatcnt=0;
            for(int i=0;i<m;++i){
                for(int j=0;j<n;++j){
                    if(seats[i][j]=='#') continue;
                    seatcnt++;
                    if(j%2==0){
                        g[S][i*n+j]=1;
                        for(int d=0;d<6;++d){
                            int ni=i+dir[d][0];
                            int nj=j+dir[d][1];
                            if(ni<0 || ni>=m || nj<0 || nj>=n || seats[ni][nj]=='#') continue;
                            g[i*n+j][ni*n+nj]=1;
                        }
                    }else{
                        g[i*n+j][T]=1;
                    }
                }
            }
            flow=0;
            EK();
            return seatcnt-flow;
        }
        
        void EK(){
            while(true){
                vector<int> pre(m*n+2,-1);
                bfs(pre);
                if(pre[T]==-1) break;
                int v=T;
                while(true){
                    int u=pre[v];
                    g[u][v]--;
                    g[v][u]++;
                    v=u;
                    if(v==S) break;
                }
                flow++;
            }
        }
        
        void bfs(vector<int> &pre){
            queue<int> q;
            q.push(S);
            vector<int> visited(m*n+2,0);
            visited[S]=1;
            while(!q.empty()){
                int cur=q.front();
                q.pop();
                for(int i=0;i<m*n+2;++i){
                    if(visited[i]==0 && g[cur][i]==1){
                        visited[i]=1;
                        q.push(i);
                        pre[i]=cur;
                    }
                }
            }
        }
        
    };
  • 相关阅读:
    HDU 1086 You can Solve a Geometry Problem too(水题,判断线段相交)
    2011ACM福州网络赛第一题 A Card Game(水题)
    Lottery hdu1099
    卡特兰数 ACM 数论
    (转)CXF的Exception问题
    简单PS合成图像(抹去某个人等)
    摄影技巧
    PS中文字变形
    螺旋阵(递归和非递归)
    路径与滤镜和自定义工具
  • 原文地址:https://www.cnblogs.com/FEIIEF/p/12293928.html
Copyright © 2011-2022 走看看