cogs2398 切糕 最小割

链接: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\n",ans);
93 }
94 int sb=haha();
95 int main(){;}
cogs2398

 

posted @ 2017-07-31 11:40  ccc000111  阅读(148)  评论(0编辑  收藏  举报