1. 程式人生 > >codeforces-gym101982E(最小割)

codeforces-gym101982E(最小割)

str depth ace ++ 我們 最小割 dinic min fine

題意:給你一個長為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\n"; else cout<<ans<<endl; return 0; }

codeforces-gym101982E(最小割)