SCU3033 Destroying a Painting(最小费用最大流)
2016-04-07 16:46
555 查看
题目大概说有一个有n*m个格子的画板,画板上每个格子都有颜色,现在要把所有格子的颜色改成红、绿或者蓝,改变的代价是二者RGB值的曼哈顿距离,还要求红绿蓝格子个数的最大值和最小值要尽可能接近,问最少的代价是多少。
红绿蓝三色的个数是可以直接确定的,分别考虑几个情况就OK了,然后就是根据红绿蓝的个数构图跑最小费用最大流。。
红绿蓝三色的个数是可以直接确定的,分别考虑几个情况就OK了,然后就是根据红绿蓝的个数构图跑最小费用最大流。。
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define INF (1<<30) #define MAXN 444 #define MAXM 444*888 struct Edge{ int u,v,cap,cost,next; }edge[MAXM]; int head[MAXN]; int NV,NE,vs,vt; void addEdge(int u,int v,int cap,int cost){ edge[NE].u=u; edge[NE].v=v; edge[NE].cap=cap; edge[NE].cost=cost; edge[NE].next=head[u]; head[u]=NE++; edge[NE].u=v; edge[NE].v=u; edge[NE].cap=0; edge[NE].cost=-cost; edge[NE].next=head[v]; head[v]=NE++; } bool vis[MAXN]; int d[MAXN],pre[MAXN]; bool SPFA(){ for(int i=0;i<NV;++i){ vis[i]=0; d[i]=INF; } vis[vs]=1; d[vs]=0; queue<int> que; que.push(vs); while(!que.empty()){ int u=que.front(); que.pop(); for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(edge[i].cap && d[v]>d[u]+edge[i].cost){ d[v]=d[u]+edge[i].cost; pre[v]=i; if(!vis[v]){ vis[v]=1; que.push(v); } } } vis[u]=0; } return d[vt]!=INF; } int MCMF(){ int res=0; while(SPFA()){ int flow=INF,cost=0; for(int u=vt; u!=vs; u=edge[pre[u]].u){ flow=min(flow,edge[pre[u]].cap); } for(int u=vt; u!=vs; u=edge[pre[u]].u){ edge[pre[u]].cap-=flow; edge[pre[u]^1].cap+=flow; cost+=flow*edge[pre[u]].cost; } res+=cost; } return res; } inline void in(int &ret){ char c; ret=0; while(c=getchar(),c<'0'||c>'9'); while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar(); } int n,m,R[22][22],G[22][22],B[22][22]; int get(int r,int g,int b){ vs=n*m+3; vt=vs+1; NV=vt+1; NE=0; memset(head,-1,sizeof(head)); addEdge(n*m,vt,r,0); addEdge(n*m+1,vt,g,0); addEdge(n*m+2,vt,b,0); for(int i=0; i<n; ++i){ for(int j=0; j<m; ++j){ addEdge(vs,i*m+j,1,0); addEdge(i*m+j,n*m,1,abs(255-R[i][j])+G[i][j]+B[i][j]); addEdge(i*m+j,n*m+1,1,R[i][j]+abs(255-G[i][j])+B[i][j]); addEdge(i*m+j,n*m+2,1,R[i][j]+G[i][j]+abs(255-B[i][j])); } } return MCMF(); } int main(){ int t; in(t); for(int cse=1; cse<=t; ++cse){ in(n); in(m); for(int i=0; i<n; ++i){ for(int j=0; j<m; ++j){ in(R[i][j]); in(G[i][j]); in(B[i][j]); } } int ans=INF; if(n*m%3==0){ ans=min(ans,get(n*m/3,n*m/3,n*m/3)); }else if(n*m%3==1){ ans=min(ans,get(n*m/3+1,n*m/3,n*m/3)); ans=min(ans,get(n*m/3,n*m/3+1,n*m/3)); ans=min(ans,get(n*m/3,n*m/3,n*m/3+1)); }else{ ans=min(ans,get(n*m/3+1,n*m/3+1,n*m/3)); ans=min(ans,get(n*m/3+1,n*m/3,n*m/3+1)); ans=min(ans,get(n*m/3,n*m/3+1,n*m/3+1)); } printf("Case %d: %d\n",cse,ans); } return 0; }
相关文章推荐
- 涂鸦|绘制|draw|paint|view的绘制|undo|redo|恢复|撤销|保存
- apt-get couldn't be verified because the public key is not available: NO_PUBKEY XXX
- 7.5 mail_copy函数:向文件系统写入邮件
- 7.4 deliver_mailbox_file函数:以mbox格式接收邮件
- 7.4 deliver_mailbox_file函数:以mbox格式接收邮件
- 7.3 deliver_maildir函数:以Maildir格式接收邮件
- Ehcache项目启动时报Update check failed异常的解决方法
- 6.6 移信和 fairness策略
- 6.3.3 sendmail的别名文件和.forward文件
- RAID阵列的迁移
- LeetCode(31)-Factorial Trailing Zeroes
- LeetCode(31)-Factorial Trailing Zeroes
- LeetCode(31)-Factorial Trailing Zeroes
- 关于快速报错fail-fast想说的之fail-fast的避免方法(二)
- com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method 错误处理
- Postfix-2.11+Dovecot-2.0.9+MySQL+Nginx+Cyrus-sasl+Extmail-1.2实现基于虚拟用户的邮件系统架构
- JetBrains Makes its Products Free for Students(JetBrains 对学生免费了)
- zz:Unable to open log device ‘/dev/log/main’: No such file or directory
- 百度地图(BaiduMap)定位工具类封装和使用
- postgres error : failed to read kind from backend