zoukankan      html  css  js  c++  java
  • bzoj 3144: [Hnoi2013]切糕 最小割

    3144: [Hnoi2013]切糕

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 681  Solved: 375
    [Submit][Status]

    Description

    Input

    第一行是三个正整数P,Q,R,表示切糕的长P、 宽Q、高R。第二行有一个非负整数D,表示光滑性要求。接下来是R个P行Q列的矩阵,第z个 矩阵的第x行第y列是v(x,y,z) (1≤x≤P, 1≤y≤Q, 1≤z≤R)。 
    100%的数据满足P,Q,R≤40,0≤D≤R,且给出的所有的不和谐值不超过1000。

    Output

    仅包含一个整数,表示在合法基础上最小的总不和谐值。

    Sample Input

    2 2 2
    1
    6 1
    6 1
    2 6
    2 6

    Sample Output

    6

    HINT

    最佳切面的f为f(1,1)=f(2,1)=2,f(1,2)=f(2,2)=1

      一类经典的方案选择型最小割,感觉,非常神奇,不过这个是稠密图把我以前的dinic直接卡TLE了,发现一定要判断maxf==0时直接退出。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define MAXN 50
    #define MAXH 50
    #define MAXE MAXV*10
    #define MAXV MAXN*MAXN*MAXH
    #define INF 0x3f3f3f3f
    const int mov[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
    struct Edge
    {
            int np,val;
            Edge *next,*neg;
    }E[MAXE],*V[MAXV];
    int sour,sink=1;
    int tope=-1;
    void addedge(int x,int y,int z)
    {
    //        printf("Add:%d %d %d
    ",x,y,z);
            E[++tope].np=y;
            E[tope].val=z;
            E[tope].next=V[x];
            V[x]=&E[tope];
    
            E[++tope].np=x;
            E[tope].val=0;
            E[tope].next=V[y];
            V[y]=&E[tope];
    
            V[x]->neg=V[y];
            V[y]->neg=V[x];
    }
    int q[MAXV];
    int vis[MAXV],bfstime=0;
    int lev[MAXV];
    int bfs()
    {
            int head=-1,tail=0;
            Edge *ne;
            int now;
            q[0]=sour;
            vis[sour]=++bfstime;
            while (head<tail)
            {
                    now=q[++head];
                    for (ne=V[now];ne;ne=ne->next)
                    {
                            if (!ne->val || vis[ne->np]==bfstime)continue;
                            vis[ne->np]=bfstime;
                            q[++tail]=ne->np;
                            lev[ne->np]=lev[now]+1;
                    }
            }
            return vis[sink]==bfstime;
    }
    int dfs(int now,int maxf)
    {
            int t,ret=0;
            if (now==sink)return maxf;
            Edge *ne;
            for (ne=V[now];maxf && ne;ne=ne->next)
            {
                    if (!ne->val || lev[ne->np]!=lev[now]+1)continue;
                    t=dfs(ne->np,min(maxf,ne->val));
                    ne->val-=t;
                    ne->neg->val+=t;
                    maxf-=t;
                    ret+=t;
            }
            if (maxf)lev[now]=-1;
            return ret;
    }
    int dinic()
    {
            int ret=0;
            while (bfs())
            {
                    ret+=dfs(sour,INF);
            }
            return ret;
    }
    int n,m,h;
    int gid(int x,int y,int z)
    {
            return 2+x*m+y+z*m*n;
    }
    int a[MAXN][MAXN][MAXH];
    int main()
    {
            freopen("input.txt","r",stdin);
            int i,j,k,k2,x,y,z;
            scanf("%d%d%d",&n,&m,&h);
            int d;
            scanf("%d",&d);
            for (k=1;k<=h;k++)
                    for (i=1;i<=n;i++)
                            for (j=1;j<=m;j++)
                                    {
                                            scanf("%d",&a[i][j][k]);
                                            addedge(gid(i,j,k-1),gid(i,j,k),a[i][j][k]);
                                    }
            for (i=1;i<=n;i++)
                    for (j=1;j<=m;j++)
                            for (k=1;k+d<=h;k++)
                                    for (k2=0;k2<4;k2++)
                                            if (i+mov[k2][0]>0 && i+mov[k2][0]<=n && j+mov[k2][1]>0 && j+mov[k2][1]<=m)
                                            {
                                            //        addedge(gid(i,j,k),gid(i+mov[k2][0],j+mov[k2][1],k+d),INF);
                                                    addedge(gid(i,j,k+d),gid(i+mov[k2][0],j+mov[k2][1],k),INF);
                                            }
            for (i=1;i<=n;i++)
                    for (j=1;j<=m;j++)
                    {
                            addedge(sour,gid(i,j,0),INF);
                            addedge(gid(i,j,h),sink,INF);
                    }
            printf("%d
    ",dinic());
    }
    by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载

    本博客已停用,新博客地址:http://mhy12345.xyz

  • 相关阅读:
    php通过ip获取地理位置的方法
    python程序怎么运行起来的
    php cURL学习 一个post提交反馈的小例子
    如何运行Python程序
    python初学者的建议
    php5.4新特性实践
    php中json_encode与json_decode注意事项
    Apanta安装Emmet(Zencoding)
    office 2013 电话激活步骤
    js中encodeURI()与encodeURIComponent()区别
  • 原文地址:https://www.cnblogs.com/mhy12345/p/4265247.html
Copyright © 2011-2022 走看看