zoukankan      html  css  js  c++  java
  • [CodeVs1227]方格取数2(最大费用最大流)

      网络流24题的坑还没填完,真的要TJ?

      题目大意:一个n*n的矩阵,每格有点权,从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来,该格子的数就变成0,这样一共走K次,现在要求K次所达到的方格的数的和最大。

      啊简单的费用流。每个点i拆成i和i',连一条容量为1的边价值为点权,再连一条容量inf的边价值为0来让这个点能被经过,然后S连(1,1)容量k价值0,i'和右、下的点连容量inf价值0的边,(n,n)'连T容量inf价值0,跑最大费用最大流。

      MDZZ看见n50我就开50,这是矩阵啊喂

    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int inf=1000000000,maxn=5100;
    struct poi{int dis,pos;};
    struct zs{int too,pre,c,cf,v,f;}e[1000010];
    priority_queue<poi>q;
    bool operator <(poi a,poi b){return a.dis<b.dis;};
    int n,k,z,tot,sum,ans;
    int last[maxn],dist[maxn],pre[maxn];
    bool v[maxn];
    void read(int &k)
    {
        k=0;int f=1;char c=getchar();
        while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
        while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
        k*=f;
    }
    void add(int x,int y,int c,int v)
    {
        e[++tot].too=y;e[tot].c=e[tot].cf=c;e[tot].v=v;
        e[tot].pre=last[x];last[x]=tot;
        e[++tot].too=x;e[tot].v=-v;
        e[tot].pre=last[y];last[y]=tot;
    }
    void spfa(int x)
    {
        for(int i=0;i<=sum;i++)pre[i]=-1,dist[i]=-inf,v[i]=0;
        dist[x]=0;v[x]=1;q.push((poi){0,x});
        while(!q.empty())
        {
            int now=q.top().pos;q.pop();
            for(int i=last[now],too=e[i].too;i;i=e[i].pre,too=e[i].too)
            if(e[i].cf)
            if(dist[too]<dist[now]+e[i].v)
            {
                dist[too]=dist[now]+e[i].v;pre[too]=i;
                if(!v[too])v[too]=1,q.push((poi){dist[too],too});
            }
            v[now]=0;
        }
    }
    void ford(int s,int t)
    {
        spfa(s);
        while(pre[t]!=-1)
        {
            int mincf=inf;
            for(int i=pre[t];i!=-1;i=pre[e[i^1].too])
            mincf=min(mincf,e[i].cf);
            ans+=dist[t]*mincf;
            for(int i=pre[t];i!=-1;i=pre[e[i^1].too])
            {
                e[i].f+=mincf;e[i^1].f=-e[i].f;
                e[i].cf-=mincf;e[i^1].cf+=mincf;
            }
            spfa(s);
        }
    }
    int num(int x,int y){return (x-1)*n+y;}
    int main()
    {
        tot=1;
        read(n);read(k);sum=2*n*n+1;
        add(0,1,k,0);add(2*n*n,sum,k,0);
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            read(z);
            add(num(i,j),num(i,j)+n*n,1,z);
            add(num(i,j),num(i,j)+n*n,inf,0);
            if(i!=n)add(num(i,j)+n*n,num(i+1,j),inf,0);
            if(j!=n)add(num(i,j)+n*n,num(i,j+1),inf,0);
        }
        ford(0,sum);
        printf("%d
    ",ans);
    }
    View Code
  • 相关阅读:
    了解 DICOM 基本协议与其相关
    C# PropertyInfo 反射实体部分字段
    ref(引用参数) 和 out(输出参数) 区别
    Linq Where Expression<Func<T,bool>> 查询条件
    随笔规范
    C# 集合分析
    C# 几种常用的数据类型
    关于 C# 方法参数的理解
    打算开始写博客了
    有趣的算法、逻辑面试题
  • 原文地址:https://www.cnblogs.com/Sakits/p/6891963.html
Copyright © 2011-2022 走看看