zoukankan      html  css  js  c++  java
  • poj3422 最小费用最大流

    上一题的模板应用,好久没做图论,结果建图一塌糊涂。。。

    题意,给出一个矩阵,求从左上角到右下角走k次使路上所得的权值最大,其中经过一个权值后,该点权值清零。

    思路:建图,每一个格子为一个点,同时衍生另外一个点,用来存清零后的路线,则每个点有两条路,一条是容量为1,权值为给出的值,一条为容量为k,权值为0;

    因为求得是最大,所以建图的时候用1000减去原来的数,求出的最小费再用k*2(n-1)*1000减去,所得的值就为最大值了。

    算是理解一下别人的模板吧,建图用时间比较长,最后建完图后,发现TLE了,结果去把范围给开大后,AC了,难道范围小了不应该RE么。。。囧

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    using namespace std;
    #define typef int
    #define typec int
    #define maxn 6000
    #define maxm 30005
    #define N maxn + 2
    #define E maxm * 4 + 4
    const typef inff = 0x3f3f3f3f;
    const typec infc = 0x3f3f3f3f;
    int map[55][55];
    struct network
    {
        int nv, ne, pnt[E], nxt[E];
        int vis[N], que[N], head[N], pv[N], pe[N];
        typef flow, cap[E];
        typec cost, dis[E], d[N];
        void addedge(int u, int v, typef c, typec w)
        {
            pnt[ne] = v;
            cap[ne] = c;
            dis[ne] = +w;
            nxt[ne] = head[u];
            head[u] = (ne++);
            pnt[ne] = u;
            cap[ne] = 0;
            dis[ne] = -w;
            nxt[ne] = head[v];
            head[v] = (ne++);
        }
        int mincost(int src, int sink)
        {
            int i, k, f, r;
            typef mxf;
            for (flow = 0, cost = 0;;)
            {
                memset(pv, -1, sizeof(pv));
                memset(vis, 0, sizeof(vis));
                for (i = 0; i < nv; ++i)
                    d[i] = infc;
                d[src] = 0;
                pv[src] = src;
                vis[src] = 1;
                for (f = 0, r = 1, que[0] = src; r != f;)
                {
                    i = que[f++];
                    vis[i] = 0;
                    if (N == f)
                        f = 0;
                    for (k = head[i]; k != -1; k = nxt[k])
                        if (cap[k] && dis[k] + d[i] < d[pnt[k]])
                        {
                            d[pnt[k]] = dis[k] + d[i];
                            if (0 == vis[pnt[k]])
                            {
                                vis[pnt[k]] = 1;
                                que[r++] = pnt[k];
                                if (N == r)
                                    r = 0;
                            }
                            pv[pnt[k]] = i;
                            pe[pnt[k]] = k;
                        }
                }
                if (-1 == pv[sink])
                    break;
                for (k = sink, mxf = inff; k != src; k = pv[k])
                    if (cap[pe[k]] < mxf)
                        mxf = cap[pe[k]];
                flow += mxf;
                cost += d[sink] * mxf;
                for (k = sink; k != src; k = pv[k])
                {
                    cap[pe[k]] -= mxf;
                    cap[pe[k] ^ 1] += mxf;
                }
            }
            return cost-1000+map[1][1];
        }
        void build(int v,int n,int k)
        {
            nv = v;
            ne = 0;
            memset(head, -1, sizeof(head));
            int x, y;
            typec w;
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                {
                    scanf("%d",&map[i][j]);
                    map[i][j]=1000-map[i][j];
                }
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                if(i-1>=1&&j-1<=0)
                {
                    addedge(n*(i-2)+j, n*(i-1)+j, 1, map[i][j]);
                    addedge(n*(i-2)+j,n*(i-1)+j+n*n,k,1000);
                    addedge(n*(i-1)+j+n*n, n*(i-1)+j, k, 0);
                }
                else if(j-1>=1&&i-1<=0)
                {
                    addedge(n*(i-1)+j-1,n*(i-1)+j, 1, map[i][j]);
                    addedge(n*(i-1)+j-1,n*(i-1)+j+n*n,k,1000);
                    addedge(n*(i-1)+j+n*n, n*(i-1)+j, k, 0);
                }    //2*n+n*n
                else if(j-1>=1&&i-1>=1)
                {
                    addedge(n*(i-1)+j-1,n*(i-1)+j+n*n,k,0);
                    addedge(n*(i-2)+j,  n*(i-1)+j+n*n,k,0);
                    addedge(n*(i-2)+j,  n*(i-1)+j, k, 1000);
                    addedge(n*(i-1)+j-1,n*(i-1)+j, k, 1000);
                    addedge(n*(i-1)+j+n*n,n*(i-1)+j, 1, map[i][j]);
    
                }
    
            }
            addedge(0, 1, k, 1000);     //答案加上map【1】【1】;
            addedge(n*n, 2*n*n+1, k, 0);
        }
    } g;
    
    int n, m,k;
    
    int main()
    {
        //freopen("t.txt", "r", stdin);
        scanf("%d%d", &n, &k);
        g.build(2*n*n + 2,n,k);
        if(k==0)
            printf("0\n");
        else
        printf("%d\n",k*(2*n-1)*1000-g.mincost(0, 2*n*n + 1));
        return 0;
    }
    


     

  • 相关阅读:
    Spring Cloud Consul Config 知识点
    RabbitMQ 的 docker 镜像使用
    Spring Cloud Config 知识点
    漫画:什么是服务熔断?
    Flux 和 Mono 的区别
    同时引入依赖:spring-cloud-starter-gateway 和 spring-boot-starter-web,报错
    Feign 报错:The bean 'service-producer.FeignClientSpecification', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled.
    Feign和OpenFeign的区别
    Maven 报错:Compilation of Maven projects is supported only if external build is started from an IDE.
    使用 application.properties 中配置的属性,举例:@Value("${server.port}")
  • 原文地址:https://www.cnblogs.com/amourjun/p/5134145.html
Copyright © 2011-2022 走看看