wya费用流

Posted on 2017-08-15 13:55  Amphetamine  阅读(134)  评论(0编辑  收藏  举报
#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

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