题意:给你一个长为m,宽为n的迷宫,问你从s开始,我们需要最小的花费堵住s,使得s不能到达迷宫的边界,只有字符a,b,c,d,...这样的点才能花费对应的钱将其堵住
解题思路:思考一下,裸的最小割,就是点权需要拆点,每个点拆成对应的两个点,能堵住的点拆为两个点,连条边边权为对应的花费,不能堵的点,连边,边权为inf;
代码
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<queue> #define maxn 10005 #define inf 0x3f3f3f3f using namespace std; struct Edge { int next; int to; int w; }edge[maxn]; int cnt; int head[maxn]; int cur[maxn]; int depth[maxn]; int Start,End,n,m,c; void add(int u,int v,int w) { edge[cnt].next=head[u];edge[cnt].w=w; edge[cnt].to=v;head[u]=cnt++; edge[cnt].next=head[v];edge[cnt].w=0; edge[cnt].to=u;head[v]=cnt++; } bool bfs() { memset(depth,0,sizeof(depth)); depth[Start]=1; queue<int>que;que.push(Start); while(!que.empty()) { int u=que.front();que.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(!depth[v]&&edge[i].w>0) { depth[v]=depth[u]+1;que.push(v); } } } return depth[End]; } int dfs(int u,int maxflow) { int tempflow; if(u==End) return maxflow; int add=0; for(int &i=cur[u];i!=-1;i=edge[i].next) { int v=edge[i].to; if(depth[v]==depth[u]+1&&edge[i].w>0&&(tempflow=dfs(v,min(maxflow-add,edge[i].w)))) { edge[i].w-=tempflow; edge[i^1].w+=tempflow; add+=tempflow; if(maxflow==add) break; } } return add; } int dinic() { int ans=0; while(bfs()) { for(int i=0;i<=2*(n*m)+1000;i++) cur[i]=head[i]; while(int temp=dfs(Start,inf)) ans+=temp; } return ans; } int dx[]={1,-1,0,0}; int dy[]={0,0,1,-1}; int main() { char gra[50][50]; memset(head,-1,sizeof(head));cnt=0; int a[30];int flag=0; scanf("%d%d%d",&m,&n,&c); Start=2*(n*m)+100;End=Start+1; for(int i=0;i<n;i++) scanf("%s",gra[i]); for(int i=0;i<c;i++) scanf("%d",&a[i]); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { int tmp=i*m+j; if(gra[i][j]=='.'||gra[i][j]=='B') add(tmp,tmp+n*m,inf); else add(tmp,tmp+n*m,a[gra[i][j]-'a']); for(int k=0;k<4;k++) { int tx=i+dx[k]; int ty=j+dy[k]; if(tx>=n||tx<0||ty>=m||ty<0) add(tmp+n*m,End,inf); else add(tmp+n*m,(tx*m+ty),inf); } if(gra[i][j]=='B') add(Start,tmp,inf); } } int ans=dinic(); if(ans>=inf) cout<<"-1 "; else cout<<ans<<endl; return 0; }