Time Limit: 3000MS64bit IO Format: %lld & %llu
网络流 最小割
心生绝望,用了好久的网络流模板居然是错的。
↑居然之前还侥幸能过一堆(并不)题。
______
利用边容量来限制花费:
边缘的坑必须填上,每格花费为f;
如果一个地方id是坑,将其填上,从S到id连边,容量为f;
如果一个地方id是草,在这挖坑,从id到T连边,容量为d;
建立栅栏:每格向四周连边,容量为b;
↑如此建边起到了限制最小花费的作用,如果挖坑的代价比种草小,挖坑的边先流满,反之同理,求出的最小割就是达成要求的最小花费。
求最小割即可。
第53行 if(!f)dep[u]=0; 作用是当前路径无法扩展时,切断路径,避免重复无意义DFS。
↑以前写dinic一直不知道要加这个,居然没被卡……
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int INF=1<<29; 8 const int mxn=3500; 9 const int mx[5]={0,1,0,-1,0}; 10 const int my[5]={0,0,1,0,-1}; 11 struct edge{ 12 int v,nxt,f; 13 }e[100010]; 14 int hd[mxn],mct=1; 15 int n,m,k,ans; 16 int id[120][120]; 17 int S,T; 18 void add_edge(int u,int v,int c){ 19 e[++mct].v=v;e[mct].nxt=hd[u];e[mct].f=c;hd[u]=mct;return; 20 } 21 int dep[4000]; 22 bool BFS(){ 23 queue<int>q; 24 memset(dep,0,sizeof dep); 25 dep[S]=1; 26 q.push(S); 27 while(!q.empty()){ 28 int u=q.front();q.pop(); 29 for(int i=hd[u];i;i=e[i].nxt){ 30 int v=e[i].v; 31 if(!dep[v] && e[i].f){ 32 dep[v]=dep[u]+1; 33 q.push(v); 34 } 35 } 36 } 37 return dep[T]; 38 } 39 int DFS(int u,int lim){ 40 if(u==T) return lim; 41 int tmp,f=0; 42 for(int i=hd[u];i;i=e[i].nxt){ 43 int v=e[i].v; 44 if(dep[v]==dep[u]+1 && e[i].f){ 45 tmp=DFS(v,min(lim,e[i].f)); 46 lim-=tmp; 47 f+=tmp; 48 e[i].f-=tmp; 49 e[i^1].f+=tmp; 50 if(!lim)return f; 51 } 52 } 53 if(!f)dep[u]=0; 54 return f; 55 } 56 int Dinic(){ 57 int res=0; 58 while(BFS())res+=DFS(S,1e9); 59 return res; 60 } 61 inline void init(){ 62 memset(hd,0,sizeof hd); 63 for(int i=1;i<=n;i++) 64 for(int j=1;j<=m;j++) 65 id[i][j]=(i-1)*m+j; 66 mct=1; 67 ans=0; 68 return; 69 } 70 int d,f,b; 71 char mp[120][120]; 72 int main() 73 { 74 int cas; 75 scanf("%d",&cas); 76 int i,j; 77 while(cas--){ 78 scanf("%d%d",&m,&n); 79 scanf("%d%d%d",&d,&f,&b); 80 init(); 81 S=0;T=n*m+2; 82 for(i=1;i<=n;i++)scanf("%s",mp[i]+1); 83 for(i=1;i<=n;i++) 84 for(j=1;j<=m;j++){ 85 if(i==1 || i==n || j==1 || j==m){ 86 if(mp[i][j]==‘.‘)ans+=f; 87 add_edge(S,id[i][j],INF); 88 add_edge(id[i][j],S,0); 89 } 90 else if(mp[i][j]==‘#‘){ 91 add_edge(S,id[i][j],d); 92 add_edge(id[i][j],S,0); 93 } 94 else{ 95 add_edge(id[i][j],T,f); 96 add_edge(T,id[i][j],0); 97 } 98 if(i>1){ 99 add_edge(id[i][j],id[i-1][j],b);add_edge(id[i-1][j],id[i][j],0); 100 add_edge(id[i][j],id[i-1][j],0);add_edge(id[i-1][j],id[i][j],b); 101 } 102 if(j>1){ 103 add_edge(id[i][j],id[i][j-1],b);add_edge(id[i][j-1],id[i][j],0); 104 add_edge(id[i][j-1],id[i][j],b);add_edge(id[i][j],id[i][j-1],0); 105 } 106 } 107 ans+=Dinic(); 108 printf("%d\n",ans); 109 } 110 return 0; 111 }
时间: 2024-10-05 20:41:24