zoukankan      html  css  js  c++  java
  • wya费用流

    #include<bits/stdc++.h>
    using namespace std;
    
    #define M 1005
    #define inf 0x7fffffff
    #define T 601
    struct edge{int to,next,cap,val;}e[100001];
    int n,m,t[61][10];
    int head[M],dis[M];
    int cnt=1;
    void add(int u,int v,int w,int q){
        e[++cnt].to=v;e[cnt].next=head[u];e[cnt].cap=w;e[cnt].val=q;head[u]=cnt;
        e[++cnt].to=u;e[cnt].next=head[v];e[cnt].cap=0;e[cnt].val=-q;head[v]=cnt;
    }
    int S=0,mark[M];
    int ans=0;
    bool bfs()
    {
        memset(mark,0,sizeof(mark));
        for(int i=0;i<=T;i++)dis[i]=inf;
        dis[S]=0;mark[S]=1;
        queue<int> q;
        q.push(S);
        while(!q.empty())
        {
            int now=q.front();q.pop();
            for(int i=head[now];i;i=e[i].next)
                if(e[i].cap&&dis[e[i].to]>dis[now]+e[i].val)
                {
                    dis[e[i].to]=dis[now]+e[i].val;
                    if(!mark[e[i].to])
                    {mark[e[i].to]=1;q.push(e[i].to);} 
                }
            mark[now]=0; 
        }
        if(dis[T]==inf)return 0;
        return 1;
    }
    int dfs(int x,int f)
    {
        if(x==T){mark[T]=1;return f;}
        int used=0,w;
        mark[x]=1;
        for(int i=head[x];i;i=e[i].next)
            if(!mark[e[i].to]&&e[i].cap&&dis[x]+e[i].val==dis[e[i].to])
            {
                w=f-used;
                w=dfs(e[i].to,min(e[i].cap,w));
                ans+=w*e[i].val;
                e[i].cap-=w;e[i^1].cap+=w;
                used+=w;if(used==f)return f;
            }
        return used;
    }
    void wya()
    {
        while(bfs())
        {
            mark[T]=1;
            while(mark[T])
            {
                memset(mark,0,sizeof(mark));
                dfs(0,inf);
            }
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&t[i][j]);
        for(int i=1;i<=n*m;i++)
            add(0,i,1,0);
        for(int i=n*m+1;i<=n*m+m;i++)
            add(i,T,1,0);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                for(int k=1;k<=m;k++)
                    add((i-1)*m+j,n*m+k,1,t[k][i]*j);
        wya();
        printf("%.2lf",(double)ans/m);
        return 0;
    }
    View Code

    之前不知知道为什么都是反着写的,这会正过来也对了。也没有多玄啊。

  • 相关阅读:
    用内联取代宏代码
    参数的缺省值
    令人迷惑的隐藏规则
    重载与覆盖
    重载是如何实现的?
    重载的起源
    C++函数的高级特性
    使用调试器逐步跟踪程序
    new/delete 的使用要点
    malloc/free 的使用要点
  • 原文地址:https://www.cnblogs.com/Amphetamine/p/7364706.html
Copyright © 2011-2022 走看看