GYM 101128 F.Landscaping(最小割-Dinic)
来源:互联网 发布:速卖通数据分析网站 编辑:程序博客网 时间:2024/06/08 16:15
Description
一块n*m的草坪,有两种高度的草,#表示较高的草,.表示较矮的草,现在要从左往右和从上往下用收割机收割,在相同高度的草坪上收割机不耗油,当高度变化时需要耗花费为a的油,还可以花费b改变任一块草坪的高度,问这n+m排收割机扫过这块草坪需要的最小花费
Input
第一行四整数n,m,a,b分别表示草坪行列数和两种花费,之后一个n*m矩阵表示该草坪(1<=n,m<=50,1<=a,b<=1e5)
Output
输出最小花费
Sample Input
Sample Output
11000
Solution
把高草坪看做一个集合S,矮草坪看做一个集合E,问题可以的当做是把这n*m个点分成这两个集合所需的最小代价,高草坪变成矮草坪和矮草坪变成高草坪花费代价b,每块草坪和其四周的草坪之间花费代价a表示高度变化的代价(同样高度也要连,因为不知道是否要改变其中某块的高度,而且如果两块草坪最终高度相同那么就会被分在同一个集合中,那么这个代价就不会被统计),即为求这个图的最小割
Code
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define maxn 3333#define maxm 2222222#define INF 0x3f3f3f3fint head[maxn],cur[maxn],d[maxn],st[maxm],s,e,no;//s为源点,e为汇点,n为点数,no为边数 struct point{ int u,v,flow,next; point(){}; point(int x,int y,int z,int w):u(x),v(y),next(z),flow(w){};}p[maxm];void add(int x,int y,int z)//从x到y建容量为z的边 { p[no]=point(x,y,head[x],z);//前向弧,标号为偶 head[x]=no++; p[no]=point(y,x,head[y],0);//后向弧,标号为奇 head[y]=no++;}void init()//初始化 { memset(head,-1,sizeof(head)); no=0;}bool bfs(){ int i,x,y; queue<int>q; memset(d,-1,sizeof(d)); d[s]=0; q.push(s); while(!q.empty()) { x=q.front(); q.pop(); for(i=head[x];i!=-1;i=p[i].next) { if(p[i].flow&& d[y=p[i].v]<0) { d[y]=d[x]+1; if(y==e) return true; q.push(y); } } } return false;}ll dinic()//最大流 { int i,loc,top,x=s,nowflow; ll maxflow=0; while(bfs()) { memcpy(cur,head,sizeof(head)); top=0; while(true) { if(x==e) { nowflow=INF; for(i=0;i<top;i++) { if(nowflow>p[st[i]].flow) { nowflow=p[st[i]].flow; loc=i; } } for(i=0;i<top;i++) { p[st[i]].flow-=nowflow; p[st[i]^1].flow+=nowflow; } maxflow+=nowflow; top=loc; x=p[st[top]].u; } for(i=cur[x];i!=-1;i=p[i].next) if(p[i].flow&&d[p[i].v]==d[x]+1) break; cur[x]=i; if(i!=-1) { st[top++]=i; x=p[i].v; } else { if(!top) break; d[x]=-1; x=p[st[--top]].u; } } } return maxflow;}int n,m,a,b;char c[55][55];int dx[]={-1,0,1,0};int dy[]={0,-1,0,1};int main(){ while(~scanf("%d%d%d%d",&n,&m,&a,&b)) { for(int i=1;i<=n;i++)scanf("%s",c[i]+1); s=0,e=n*m+1; init(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(c[i][j]=='#')add(s,(i-1)*m+j,b); else add((i-1)*m+j,e,b); for(int k=0;k<4;k++) { int ii=i+dx[k],jj=j+dy[k]; if(ii<1||ii>n||jj<1||jj>m)continue; add((i-1)*m+j,(ii-1)*m+jj,a); } } printf("%I64d\n",dinic()); } return 0;}
0 0
- GYM 101128 F.Landscaping【最小割--Dinic】
- GYM 101128 F.Landscaping(最小割-Dinic)
- Codeforces Gym 101128F (UVA Live 7277) Landscaping 最小割
- GYM101128F.Landscaping(最小割-Dinic)
- GYM 101149 D.Behind the Wall(最小割-Dinic)
- 【BZOJ4439】[Swerc2015]Landscaping【最小割】
- Landscaping Gym
- POJ 3308 Paratroopers(最小割+Dinic)
- Dinic模板(最大流最小割)
- dinic最大流模板(最小割)
- GYM 100694 F.The Berland Championship(最大流-Dinic)
- BOJ 热身赛 F题 解题报告 [最大流最小割 dinic]
- HDU 1565 方格取数(1)(最小割-Dinic)
- POJ 3469 Dual Core CPU(最小割-Dinic)
- Dinic 算法求最大流(最小割) POJ 2536
- HDU 6142 Jedi Council(最小割-Dinic)
- HDU 6126 Give out candies(最小割-Dinic)
- zoj 2676 dinic模板求实型最小割(可做dinic模板)
- angular js ng-change的用法
- js执行顺序(Compile phase and execute phase)
- 详解 JavaScript 闭包
- Java学习的相关书籍
- 编程思考
- GYM 101128 F.Landscaping(最小割-Dinic)
- java使用opi导出excel
- 创建高性能的索引
- C# matlab 混编
- 这样写就可以让自己的论文严谨有序
- OSI七层模型详解
- 快速排序
- codeforce 763A
- intent.setFlags方法中的参数值含义