zoukankan      html  css  js  c++  java
  • 【P2405】方格取数问题加强版(费用流)


    考虑如何建图。还是老样子先拆点,然后把每两个点之间连接两条边,一条流量为1,费用为-点权,处理是否走这个点。一条流量无限,没有费用,因为哪怕一个点选过了,它的地方还是可以重复走过去的。 然后把经由一个点能到达的另一个点连边。因为要走k次,所以由s向1号点入点连边,n号点出点向t连边,流量为k,费用为0。然后一边最小费用最大流板子即可。 然后发现这些个题解里没有用原始对偶来实现的,所以弱弱的拿出自己代码,勉强还是能在最优解第一页里的,膜拜那些50ms都不到就跑完的dalao们。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define ll long long
    #define rp (i-1)*n+j 
    #define cp (i-1)*n+j+n*n 
    #define inf 50000000
    #define re register
    using namespace std;
    struct po
    {
        int from,to,dis,nxt,w;
    }edge[250001];
    int head[250001],cur[1000001],dep[60001],n,m,s,t,u,num=-1,x,y,l,tot,sum,k;
    int dis[6001],b[6001],xb[20001],flow[20001],a[55][55];
    inline int read()
    {
        int x=0,c=1;
        char ch=' ';
        while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
        while(ch=='-')c*=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();
        return x*c;
    }
    inline void add_edge(int from,int to,int w,int dis)
    {
        edge[++num].nxt=head[from];
        edge[num].to=to;
        edge[num].w=w;
        edge[num].dis=dis;
        head[from]=num;
    }
    inline void add(int from,int to,int w,int dis)
    {
        add_edge(from,to,w,dis);
        add_edge(to,from,0,-dis);
    }
    inline bool spfa()
    {
        memset(b,0,sizeof(b));
        memset(dis,100,sizeof(dis));
        deque<int> q;
        while(!q.empty())
        q.pop_back();
        dis[t]=0;b[t]=1;
        q.push_back(t);
        while(!q.empty())
        {
            int u=q.front();
            q.pop_front();
            b[u]=0;
            for(re int i=head[u];i!=-1;i=edge[i].nxt)
            {
                int v=edge[i].to;
                if(edge[i^1].w>0&&dis[v]>dis[u]-edge[i].dis)
                {
                    dis[v]=dis[u]-edge[i].dis;
                    if(!b[v])
                    {
                        b[v]=1;
                        if(!q.empty()&&dis[v]<dis[q.front()])
                        q.push_front(v);
                        else
                        q.push_back(v);
                    }
                }
            }
        }
        return dis[s]<inf;
    }
    inline int dfs(int u,int low)
    {
        if(u==t)
        {
            b[t]=1;
            return low;
        }
        int diss=0;
        b[u]=1;
        for(re int i=head[u];i!=-1;i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(!b[v]&&edge[i].w!=0&&dis[v]==dis[u]-edge[i].dis)
            {
                int check=dfs(v,min(low,edge[i].w));
                if(check>0)
                {
                    tot+=check*edge[i].dis;
                    low-=check;
                    diss+=check;
                    edge[i].w-=check;
                    edge[i^1].w+=check;
                    if(low==0) break;
                }
            }
        }
        return diss;
    }
    inline void max_flow()
    {
        int ans=0;
        while(spfa())
        {
            b[t]=1;
            while(b[t]==1)
            {
                memset(b,0,sizeof(b));
                ans=dfs(s,inf);
            }
        }
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        n=read();k=read();
        for(re int i=1;i<=n;i++)
         for(re int j=1;j<=n;j++)
            a[i][j]=read();
        s=0;t=n*n*2+1;
        add(s,1,k,0);add(n*n*2,t,k,0);
        for(re int i=1;i<=n;i++)
         for(re int j=1;j<=n;j++)
         {
            add(rp,cp,1,-a[i][j]);
            add(rp,cp,inf,0);
            if(i<n)
            add(cp,rp+n,inf,0);
            if(j<n)
            add(cp,rp+1,inf,0);
         }
        max_flow();
        cout<<-tot;
    } 
  • 相关阅读:
    ThinkPHP5 动态生成图片缩略图
    2020年python学习进阶方向
    2020年一线大厂月薪35K的Python开发要求
    swoole扩展怎么用
    如何在PHP框架里把Traits使用起来
    php与Redis实现一个100万用户的投票项目,如何实现实时查看投票情况?
    PHP高并发和大流量的解决方案
    phper使用MySQL 针对千万级的大表要怎么优化?
    swoole加密可破解吗
    轻松玩转windows之redis实战
  • 原文地址:https://www.cnblogs.com/victorique/p/8427983.html
Copyright © 2011-2022 走看看