题面太长了请各位自行品尝—>老C的方块
分析:
我们要解决掉所有使人弃疗的组合,还要保证花费最小,容易想到最小割(当然你要是想费用流的话,我们就没办法定义流量了)
我们来分析一下那些令人弃疗的组合,他们的规律:
首先是两个和特殊边直接相邻的方块(以下简称轴方块),加上两侧各任意一个边缘方块,组成了令人弃疗的组合。
所以我们有三种选择(准确地说其实只有两种,前两种本质一样):
1. 将和特殊边左侧的轴方块相连的所有边缘方块都破坏掉。
2. 将和特殊边右侧的轴方块相连的所有边缘方块都破坏掉。
3. 破坏掉任意一个轴方块。
我们还可以发现,特殊边两侧的部分相互独立。
所以我们可以应用染色技巧,怎么染色?当然是按照坐标(i+j)的奇偶性将图染成两种颜色。
之后从对于边缘方块及其轴方块,白点向黑点连边,流量为inf、
相邻的轴方块,黑点向白点连边,容量为较小的那个的代价、
之后S向白色边缘方块连边,容量为其代价,黑边缘方块向T连边,容量为其代价。
跑最小割。
细节很多,一着不慎满盘皆输!
代码:
#include<bits/stdc++.h>
#define ms(a,x) memset(a,x,sizeof(a))
using namespace std;int tot=;
const int N=,inf=0x3f3f3f3f;
int S,T,n,m,k,h[N],c=,q[N],d[N];
struct node{int y,z,nxt;}e[N*];
struct kuai{int x,y,w,id;}p[N];
void add(int x,int y,int z){
e[++c]=(node){y,z,h[x]};h[x]=c;
e[++c]=(node){x,,h[y]};h[y]=c;
} bool bfs(){
int f=,t=;ms(d,-);
q[++t]=S;d[S]=;
while(f<=t){
int x=q[f++];
for(int i=h[x],y;i;i=e[i].nxt)
if(d[y=e[i].y]==-&&e[i].z)
d[y]=d[x]+,q[++t]=y;
} return (d[T]!=-);
} int dfs(int x,int f){
if(x==T) return f;int w,tmp=;
for(int i=h[x],y;i;i=e[i].nxt)
if(d[y=e[i].y]==d[x]+&&e[i].z){
w=dfs(y,min(e[i].z,f-tmp));
if(!w) d[y]=-;e[i].z-=w;
e[i^].z+=w;tmp+=w;
if(tmp==f) return f;
} return tmp;
} void dinic(){
while(bfs()) tot+=dfs(S,inf);
} bool cpx(kuai a,kuai b){
return a.x!=b.x?a.x<b.x:a.y<b.y;
} bool cpy(kuai a,kuai b){
return a.y!=b.y?a.y<b.y:a.x<b.x;
} int main(){
scanf("%d%d%d",&n,&m,&k);S=;T=k+;
for(int i=;i<=k;p[i].id=i,i++)
scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].w);
p[].x=p[].y=p[k+].x=p[k+].y=;
sort(p+,p+k+,cpx);
for(int i=;i<=k;i++)
if(p[i+].x==p[i].x&&p[i+].y==p[i].y+){
if(((p[i].x+p[i].y)&)==)
add(p[i].id,p[i+].id,inf);
else add(p[i+].id,p[i].id,inf);
} sort(p+,p+k+,cpy);
for(int i=,val;i<=k;i++){
if(p[i+].x!=p[i].x+||p[i+].y!=p[i].y)
continue;
if(p[i].x%&&p[i].y%==((p[i].x-)/)%)
continue;
if(p[i].x%) val=min(p[i].w,p[i+].w);
else val=inf;if(p[i].y%)
add(p[i+].id,p[i].id,val);
else add(p[i].id,p[i+].id,val);
} for(int i=;i<=k;i++)
if(((p[i].x-)/)%==p[i].y%){
if((p[i].x+p[i].y)%==)
add(S,p[i].id,p[i].w);
else add(p[i].id,T,p[i].w);
} dinic();
printf("%d\n",tot);return ;
}
染色最小割