LC 1368. Minimum Cost to Make at Least One Valid Path in a Grid

link

 

 Solution 1 : min cost flow

Break each cell into two nodes i and i', connect i to i' (i+mn) with an edge with flow 1, cost 0. For each cell i, consider 4 adjacent cells j, connect i' to j with an edge with flow 1, if we can get to j without direction change, the cost is 0, else the cost is 1.
Add Source and Target point, connect Source to 0 with flow 1, cost 0; connect 2mn-1 (mn-1+mn) to T with flow 1, cost 0.
Using spfa to find the path each time, EK algo to find the max flow.

 

class Solution {
public:
    int m,n;
    int S,T;
    int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
    int head[30000];
    struct Edge{
        int to;
        int next;
        int remain;
        int fi;
    }e[300000];
    int en;
    
    void add(int from, int to, int flow, int fi){
        addEdge(from,to,flow,fi);
        addEdge(to,from,0,-fi);
    }
    
    void addEdge(int from, int to, int flow, int fi){
        e[en].next=head[from];
        e[en].to=to;
        e[en].remain=flow;
        e[en].fi=fi;
        head[from]=en;
        ++en;
    }
    
    int minCost(vector<vector<int>>& grid) {
        en=0;
        memset(head,-1,sizeof(head));
        m=grid.size();
        n=grid[0].size();
        S=2*m*n;
        T=2*m*n+1;
        
        add(S,0,1,0);
        add(2*m*n-1,T,1,0);
        for(int i=0;i<m*n;i++){
            add(i,i+m*n,1,0);
            int x=i/n;
            int y=i%n;
            for(int d=0;d<4;d++){
                int nx=x+dir[d][0];
                int ny=y+dir[d][1];
                if(nx<0 || nx>=m || ny<0 || ny>=n) continue;
                if(d+1!=grid[x][y]){
                   
                    add(i+m*n,nx*n+ny,1,1);
                }else{
                    add(i+m*n,nx*n+ny,1,0);
                }
            }
        }
        return EK();
    }
    
    int EK(){
        int res=0;
        
        while(true){
            vector<int> dis(2*m*n+2,INT_MAX);
            vector<int> pre(2*m*n+2,-1);
            spfa(pre,dis);
            if(pre[T]==-1) break;
            int v=T;
            while(true){
                int edge=pre[v];
                e[edge].remain--;
                e[edge^1].remain++;
                v=e[edge^1].to;
                if(v==S) break;
            }
            
            res+=dis[T];
        }
        return res;
    }
    
    void spfa(vector<int> &pre, vector<int> &dis){
        queue<int> q;
        vector<int> iq(2*m*n+2,0);
        
        q.push(S);
        iq[S]=1;
        dis[S]=0;
        while(!q.empty()){
            int cur=q.front();
            q.pop();
            iq[cur]=0;
            
            for(int i=head[cur];i!=-1;i=e[i].next){
                int v=e[i].to;
                
                if(e[i].remain>0 && dis[v]>dis[cur]+e[i].fi){
                    dis[v]=dis[cur]+e[i].fi;
                    pre[v]=i;
                    if(iq[v]==0){
                        iq[v]=1;
                        q.push(v);
                    }
                }
            }
        }
    }
    
   
};

 

 

Solution 2: BFS + DFS

class Solution {
public:
    int m,n;
    int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
    int cost;
    vector<vector<int>> _grid;
    int minCost(vector<vector<int>>& grid) {
        m=grid.size();
        n=grid[0].size();
        _grid=grid;
        vector<vector<int>> res(m,vector<int>(n,INT_MAX));
        queue<pair<int,int>> q;
        cost=0;
        dfs(0,0,q,res);
        while(!q.empty()){
            cost++;
            int size=q.size();
            for(int i=0;i<size;++i){
                auto cur=q.front();
                q.pop();
                for(int d=0;d<4;d++){
                    dfs(cur.first+dir[d][0],cur.second+dir[d][1],q,res);
                }
            }
        }
        return res[m-1][n-1];
    }
    
    void dfs(int r, int c, queue<pair<int,int>> &q, vector<vector<int>> &res){
        if(r<0 || r>=m || c<0 || c>=n) return;
        if(res[r][c]!=INT_MAX) return;
        res[r][c]=cost;
        q.push({r,c});
        int d=_grid[r][c]-1;
        dfs(r+dir[d][0],c+dir[d][1],q,res);
    }
};

 

posted @ 2020-03-01 15:06  feibilun  阅读(148)  评论(0编辑  收藏  举报