链接:http://cogs.pro/cogs/problem/problem.php?pid=2398
题意:找到一个最小割使损失最小。
字面意思,单纯的最小割。对于每一个点$(i,j,k)$,我们将其与它下方的点$(i,j,k-1)$,连一条容量为该点不和谐度的边,如果高度为1,连到源点,高度为n,建出一条到汇点容量无限大的边。对于高度超过限制高度的点,我们由周围下方可行点向它连容量无限大边。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 const int maxn=45,maxm=100005,inf=0x3f3f3f3f; 7 int map[maxn][maxn][maxn],ord[maxn][maxn][maxn],p,q,r,cnt,S,T,d,fx[4]={0,0,1,-1},fy[4]={1,-1,0,0}; 8 struct node 9 { 10 int from,to,flow,next; 11 }edge[maxm<<3]; 12 int head[maxm],tot; 13 void addedge(int u,int v,int w) 14 { 15 edge[tot]=(node){u,v,w,head[u]};head[u]=tot++; 16 edge[tot]=(node){v,u,0,head[v]};head[v]=tot++; 17 } 18 #include<queue> 19 int dis[maxm],g[maxm]; 20 bool bfs() 21 { 22 memset(dis,0,sizeof(dis)); 23 dis[S]=1; 24 queue<int>q;q.push(S); 25 while(!q.empty()) 26 { 27 int u=q.front();q.pop(); 28 for(int i=head[u];i!=-1;i=edge[i].next) 29 { 30 int v=edge[i].to; 31 if(edge[i].flow>0&&!dis[v]) 32 { 33 dis[v]=dis[u]+1; 34 q.push(v); 35 } 36 } 37 } 38 return dis[T]; 39 } 40 int dfs(int pos,int flow) 41 { 42 if(pos==T||!flow)return flow; 43 int f=0; 44 for(int &i=g[pos];i!=-1;i=edge[i].next) 45 { 46 int v=edge[i].to; 47 if(dis[v]==dis[pos]+1&&edge[i].flow>0) 48 { 49 int t=dfs(v,min(flow,edge[i].flow)); 50 if(t>0) 51 { 52 flow-=t;f+=t; 53 edge[i].flow-=t; 54 edge[i^1].flow+=t; 55 if(!flow)break; 56 } 57 } 58 } 59 return f; 60 } 61 int haha() 62 { 63 freopen("nutcake.in","r",stdin); 64 freopen("nutcake.out","w",stdout); 65 memset(head,-1,sizeof(head)); 66 scanf("%d%d%d",&p,&q,&r); 67 scanf("%d",&d); 68 for(int i=1;i<=p;i++) 69 for(int j=1;j<=q;j++) 70 for(int k=1;k<=r;k++)ord[i][j][k]=++cnt; 71 S=0,T=cnt+1; 72 for(int k=1;k<=r;k++) 73 for(int i=1;i<=p;i++) 74 for(int j=1;j<=q;j++) 75 { 76 int z;scanf("%d",&z); 77 if(k==1)addedge(S,ord[i][j][k],z),addedge(ord[i][j][r],T,inf); 78 else addedge(ord[i][j][k-1],ord[i][j][k],z); 79 if(k>d) 80 for(int l=0;l<4;l++) 81 { 82 int x=i+fx[l],y=j+fy[l]; 83 if(ord[x][y][k-d])addedge(ord[i][j][k],ord[x][y][k-d],inf); 84 } 85 } 86 int ans=0; 87 while(bfs()) 88 { 89 for(int i=S;i<=T;i++)g[i]=head[i]; 90 ans+=dfs(S,T); 91 } 92 printf("%d ",ans); 93 } 94 int sb=haha(); 95 int main(){;}