zoukankan      html  css  js  c++  java
  • codevs1227

    费用流,其实是求传输一个容量为k的流的最大费用。主要是建图。原点为0,和1连上一条容量为k,费用为0的边,中间每个点拆成两个1和2,连上一条边,容量为k,费用为c,再连一条容量为比k大,费用为0的边,这样是为了跑完费用之后能继续跑拆完后的点和。然后和其他边连上就可以了。n*n和汇点连上一条容量为k,费用为0的边。我就是每次跑了一个容量为1的流,求打脸,不知道对不对。

    #include<iostream>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int inf=0x3f3f3f3f;
    struct edge
    {
        int to,nxt,c,f;
    }e[30011];
    int n,k,cur,ans,cnt=1;
    int dist[30011],used[30011],pree[30011],prev[30011],g[30011];
    void link(int u,int v,int f,int c)
    {
        e[++cnt].nxt=g[u];
        g[u]=cnt;
        e[cnt].f=f;
        e[cnt].to=v;
        e[cnt].c=c;
    }
    void ins(int u,int v,int f,int c)
    {
        link(u,v,f,c);
        link(v,u,0,-c);
    }
    int Min(int x,int y)
    {
        return x<y?x:y;
    }
    bool spfa()
    {
        queue<int>q;
        memset(dist,-1,sizeof(dist));
        memset(used,0,sizeof(used));
        dist[0]=0;
        q.push(0);
        while(!q.empty())
        {
            int u=q.front(); q.pop(); 
            used[u]=0;
            for(int i=g[u];i;i=e[i].nxt)
            {
                int v=e[i].to,w=e[i].c;
                if(e[i].f&&dist[v]<dist[u]+w)
                {
                    dist[v]=dist[u]+w;
                    prev[v]=u; pree[v]=i;
                    if(!used[v])
                    {
                        q.push(v); 
                        used[v]=1;
                    }
                }
            }
        }
        return dist[10010]!=-1;
    }
    int MinCostFlow()
    {
        int u=10010,sum=inf;
        while(u)
        {
            e[pree[u]].f--;
            e[pree[u]^1].f++;
            u=prev[u];
        }
    //    cout<<dist[10010]<<endl;
        return dist[10010];
    }
    void MinFlow()
    {
        while(spfa())
        {
            cur+=MinCostFlow();
            if(cur>ans) ans=cur;
        }
        printf("%d",ans);
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                int x; scanf("%d",&x);
                ins((i-1)*n+j,(i-1)*n+j+n*n,1,x);
                ins((i-1)*n+j,(i-1)*n+j+n*n,k,0);
                if(i!=n)
                {
                    ins((i-1)*n+j+n*n,i*n+j,k,0);
                }
                if(j!=n)
                {
                    ins((i-1)*n+j+n*n,(i-1)*n+j+1,k,0);
                }
            }
        }
        ins(0,1,k,0);
        ins(n*n*2,10010,k,0);
        MinFlow();
        return 0;
    }
  • 相关阅读:
    jsp实现文件上传——douploadFile.jsp
    jsp实现文件上传——douploadFile.jsp
    jsp实现文件上传——douploadFile.jsp
    JSP实现文件上传——uploadFile.jsp
    JSP实现文件上传——uploadFile.jsp
    JSP实现文件上传——uploadFile.jsp
    JSP的JNDI简单编写
    JSP的JNDI简单编写
    JSP的JNDI简单编写
    服务降级
  • 原文地址:https://www.cnblogs.com/19992147orz/p/6087390.html
Copyright © 2011-2022 走看看