poj 3686

代码:

#include<iostream>
#include<fstream>

using namespace std;

int n,m;

int link[2501],x[51],y[2501],lx[51],ly[2501];

int map[51][51];

int w[51][2501];

int dfs(int s){
    x[s]=1;
    for(int i=1;i<=m;i++)
        if(y[i]==0&&lx[s]+ly[i]==w[s][i])
        {
            y[i]=1;
            if(link[i]==-1||dfs(link[i]))
            {
                link[i]=s;
                return 1;
            }
        }
    return 0;
}

void solve(){
    int i,j,k,s,t;
    memset(link,-1,sizeof(link));
    memset(ly,0,sizeof(ly));
    for(i=1;i<=n;i++)
    {
        lx[i]=-10000000;
        for(j=1;j<=m;j++)
            lx[i]=max(lx[i],w[i][j]);
    }

    for(s=1;s<=n;s++)
        while(1)
        {
            memset(x,0,sizeof(x));
            memset(y,0,sizeof(y));
            if(dfs(s)) break;
            k=10000000;
            for(i=1;i<=n;i++)
                if(x[i])
                for(j=1;j<=m;j++)
                    if(!y[j])
                    k=min(k,lx[i]+ly[j]-w[i][j]);
            for(i=1;i<=n;i++)
                if(x[i])
                    lx[i]-=k;
            for(i=1;i<=m;i++)
                if(y[i])
                    ly[i]+=k;
        }
    double sum=0;
    for(i=1;i<=m;i++)
        if(link[i]!=-1)
            sum+=-w[link[i]][i];
    printf("%.6lf\n",sum/n);
}



void read(){

//    ifstream cin("in.txt");
    int i,j,k,s;
    int cas;
    cin>>cas;

    while(cas--)
    {
        cin>>n>>m;

        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
                cin>>map[i][j];
               
        for(s=1;s<=n;s++)
            for(i=1;i<=n;i++)
                for(j=1;j<=m;j++)
                {
                    w[s][(i-1)*m+j]=-i*map[s][j];
                }
        m=n*m;
        solve();
    }

}

int main(){
    read();
    return 0;
}

posted on 2011-05-28 10:06  宇宙吾心  阅读(268)  评论(0)    收藏  举报

导航