hdu2255 fairly well-off big money (weighted bipartite graph Best Match) (km algorithms template title)

Problem Description

Legend in faraway places have a very wealthy village, one day, the mayor decided to carry out institutional reforms: re-distribution house.
This is a major event in relation to the housing problems of the people ah. In the village there are n rooms, there are n just ordinary people, taking into account every household should have room to live (if there are people out of homes, it is easy to cause unrest), each must be assigned to a house and can only get a house.
On the other hand, the village chief and other village leaders hope to get the maximum benefit, this village institutions will have the money. Because people are more prosperous, they can each house a certain price within the range of their economic , for example, there are three houses, one can people out 100,000 pairs between the first, the first two out of 20,000, to 200,000 between the first three. (of course, within the scope of their economy). now the problem is that village how to lead the largest distribution house to make income. (the villagers even have money to buy a house, but not necessarily be able to buy, look at the distribution of village leaders).

Input

Comprising a plurality of sets of test input data, a first data input line of each n, represents the number of (the number of people are at home) of the house, then there are n rows, each row number n i denotes the j th village name the room price (n <= 300).

Output

Please deliver maximum revenue values ​​for each set of data, each set of output per line.

Sample Input

2
100 10
15 23

Sample Output

123

analysis:

Bare title.

(Km algorithms to see this man: hehedad's blog )

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
typedef long long ll;
const int inf=0x3f3f3f3f;
const int inn=0x80808080;
using namespace std;
const int maxm=305;
int g[maxm][maxm];//权值
int a[maxm];
int b[maxm];
int amark[maxm];
int bmark[maxm];
int now[maxm];
int need[maxm];
int n;
int dfs(int x){
    amark[x]=1;
    for(int i=1;i<=n;i++){
        if(!bmark[i]){
            int temp=a[x]+b[i]-g[x][i];
            if(temp==0){
                bmark[i]=1;
                if(now[i]==-1||dfs(now[i])){
                    now[i]=x;
                    return 1;
                }
            }else{
                need[i]=min(need[i],temp);
            }
        }
    }
    return 0;
}
int km(){
    memset(now,-1,sizeof now);
    memset(b,0,sizeof b);
    for(int i=1;i<=n;i++){
        a[i]=g[i][1];
        for(int j=2;j<=n;j++){
            a[i]=max(a[i],g[i][j]);
        }
    }
    for(int i=1;i<=n;i++){
        memset(need,inf,sizeof need);
        while(1){
            memset(amark,0,sizeof amark);
            memset(bmark,0,sizeof bmark);
            if(dfs(i))break;
            int d=inf;
            for(int j=1;j<=n;j++){
                if(!bmark[j]){
                    d=min(d,need[j]);
                }
            }
            for(int j=1;j<=n;j++){
                if(amark[j]){
                    a[j]-=d;
                }
                if(bmark[j]){
                    b[j]+=d;
                }else{
                    need[j]-=d;
                }
            }
        }
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        ans+=g[now[i]][i];
    }
    return ans;
}
int main(){
    while(cin>>n){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&g[i][j]);
            }
        }
        cout<<km()<<endl;
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_44178736/article/details/92853688