1 条题解

  • 0
    @ 2025-10-8 17:04:07

    题解

    该题是基于最小费用最大流算法的网格路径问题。在n×m网格中,部分格子为源点(mp[i][j]=1),部分为汇点(mp[i][j]=2),其余为普通格子。源点可无限流出,汇点可无限流入,每个格子仅能通过一次。将每个格子抽象为图节点,源点连接所有源点格子(容量INF,费用0),汇点连接所有汇点格子(容量INF,费用0),普通格子向四邻接格子连边(容量1,费用0)。使用ISAP算法(BFS层次图+DFS找增广路)求解最大流,结果即为最多可通过的格子数。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e6,inf=0x3f3f3f3f;
    struct edge{int x,y,flow,cost,pre;}a[N];
    int alen,last[N];
    void ins(int x,int y,int flow,int cost){
    	a[++alen]={x,y,flow,cost,last[x]};last[x]=alen;
    	a[++alen]={y,x,0,-cost,last[y]};last[y]=alen;
    }
    int st,ed;
    int h[N];
    bool spfa(){
    	queue<int> q;q.push(st);
    	memset(h,0,sizeof(h));h[st]=1;
    	while(!q.empty()){
    		int x=q.front();q.pop();
    		for(int k=last[x];k;k=a[k].pre){
    			int y=a[k].y;
    			if(a[k].flow>0&&!h[y]){
    				h[y]=h[x]+1;
    				q.push(y);
    			}
    		}
    	}
    	return h[ed]>0;
    }
    int cur[N];
    int findflow(int x,int f){
    	if(x==ed) return f;
    	int sx=0;
    	for(int k=cur[x];k;k=a[k].pre){
    		cur[x]=k;
    		int y=a[k].y;
    		if(a[k].flow>0&&h[y]==h[x]+1&&sx<f){
    			int sy=findflow(y,min(f-sx,a[k].flow));
    			sx+=sy;
    			a[k].flow-=sy;a[k^1].flow+=sy;
    		}
    	}
    	if(sx==0) h[x]=-1;
    	return sx;
    }
    int mp[110][110];
    int dx[4]={0,1,0,-1};
    int dy[4]={1,0,-1,0};
    int main(){
    	alen=1;
    	int n,m;scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			scanf("%d",&mp[i][j]);
    		}
    	}
    	st=n*m+1;ed=st+1;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			if(mp[i][j]==1) ins(st,(i-1)*m+j,inf,0);
    			if(mp[i][j]==2) ins((i-1)*m+j,ed,inf,0);
    			for(int k=0;k<4;k++){
    				int x=i+dx[k],y=j+dy[k];
    				if(x>n||x<=0||y>m||y<=0) continue;
    				ins((i-1)*m+j,(x-1)*m+y,1,0);
    			}
    		}
    	}
    	int res=0;
    	while(spfa()){
    		memcpy(cur,last,sizeof(last));
    		res+=findflow(st,inf);
    	}
    	printf("%d",res);
    }
    
    • 1

    信息

    ID
    3065
    时间
    1000ms
    内存
    125MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者