【HDU

来源:互联网 发布:人类学 知乎 编辑:程序博客网 时间:2024/06/15 05:12

传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子。
这可是一件大事,关系到人民的住房问题啊。村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子。
另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出10万,对第2间出2万,对第3间出20万.(当然是在他们的经济范围内).现在这个问题就是村领导怎样分配房子才能使收入最大.(村民即使有钱购买一间房子但不一定能买到,要看村领导分配的).
Input
输入数据包含多组测试用例,每组数据的第一行输入n,表示房子的数量(也是老百姓家的数量),接下来有n行,每行n个数表示第i个村名对第j间房出的价格(n<=300)。
Output
请对每组数据输出最大的收入值,每组的输出占一行。

Sample Input
2
100 10
15 23
Sample Output
123

第一次接触 KM (o(n^2*m))算法,KM,算法是解决二分图最大边权匹配的算法,相信之前肯定接触过二分图的最大匹配把,想一下,当时我们把边权赋值1,最大匹配数目==最大边权和 。 但是有时候边权不一定为1,在这种情况下的求解最大边权和就是我们说的 ,求最大边权匹配。

这个讲的很形象
好了,概念差不多了,看一下代码

#include<bits/stdc++.h>using namespace std;#define  LL long long#define fread() freopen("in.txt","r",stdin)#define fwrite() freopen("out.txt","w",stdout)#define CLOSE() ios_base::sync_with_stdio(false)const int MAXN = 300+10;const int MAXM = 1e6;const int mod = 1e9+7;const int inf = 0x3f3f3f3f;int match[MAXN];// 匹配 int lx[MAXN],ly[MAXN];//每个的期望值 int slack[MAXN];//松弛量 int Map[MAXN][MAXN];int visx[MAXN],visy[MAXN];// 是否在当前匹配中 int nx,ny;int dfs(int x){    visx[x]=1;    for(int y=0;y<ny;y++){        if(visy[y]) continue;        int t=lx[x]+ly[y]-Map[x][y];        if(t==0){//  这样才可以匹配。             visy[y]=1;            if(match[y]==-1||dfs(match[y])) {                match[y]=x;                return 1;            }        }else if(slack[y]>t) //更新松弛度                 slack[y]=t;    }     return 0;}int KM(){    memset(match,-1,sizeof(match));    memset(ly,0,sizeof(ly));// 起始T中的期望都是0     for(int x=0;x<nx;x++){        lx[x]=-inf;  // 起始S中的期望是最大的一个 边权         for(int j=0;j<ny;j++){            if(lx[x]<Map[x][j])                 lx[x]=Map[x][j];        }    }    for(int x=0;x<nx;x++){        for(int i=0;i<ny;i++) slack[i]=inf;        while(1){            //重置,一开始都不在当前匹配中             memset(visx,0,sizeof(visx));            memset(visy,0,sizeof(visy));            if(dfs(x)) break;//匹配成功             int d=inf;// 不成功,就减少期望             for(int i=0;i<ny;i++)                 if(!visy[i]) d=min(d,slack[i]); // 找到最小的 需要减少的期望             for(int i=0;i<nx;i++)                 if(visx[i]) lx[i]-=d;            for(int i=0;i<ny;i++){                if(visy[i]) ly[i]+=d;//                else slack[i]-=d; // 更新松弛              }         }    }    int ans=0;    for(int i=0;i<ny;i++)        if(match[i]!=-1) ans+=Map[match[i]][i];    return ans;}int main(){    CLOSE();//  fread();//  fwrite();    int n;    while(scanf("%d",&n)!=EOF){        nx=ny=n;        for(int i=0;i<n;i++){            for(int j=0;j<n;j++)                scanf("%d",&Map[i][j]);        }        printf("%d\n",KM());    }    return 0;}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 狗狗得了乳腺瘤怎么办 孕28周还是臀位怎么办 怀孕五个月胎位不正怎么办 33周了胎位不正怎么办 足月胎儿不足5斤怎么办 绒癌观察期怀孕怎么办 宝宝囱门闭合晚怎么办 慢性硬脑膜下血肿复发怎么办 佝偻病导致囟门晚闭怎么办 儿童液体补多了怎么办 脑脊液鼻漏3年了怎么办 结石掉到膀胱里怎么办 肾结石引起的腰疼怎么办 肾结石小但很疼怎么办 狗狗得了尿结石怎么办 生理期第四天必须游泳怎么办 碎石后吐的厉害怎么办 白细胞高红细胞高血尿怎么办? 早期肾癌术后复发该怎么办 肾结石因运动引起尿血怎么办 宝宝大便镜检阳性潜血怎么办 尿不尽刺痛带血怎么办 狗狗拉肚子拉血怎么办 肾血肿怎么办才吸收快 体检尿蛋白高3怎么办 肾炎会引起脸肿怎么办 12小孩尿蛋白3是怎么办 肝癌介入手术后肝功能不好怎么办 屁多且臭便秘怎么办 肝癌术1年后复发怎么办 怀孕便秘怎么办或大便太干拉不出 肠鸣便秘怎么办多尿 奥司他韦过量怎么办 憋的时间长尿痛怎么办 手过敏了怎么办最简单 肾结石不痛但是有血尿怎么办 儿童医院血液科挂不到号怎么办 搬完重物手抖怎么办 弯腰搬重物腰疼怎么办 搬了重物后腰疼怎么办 例假不走公务员体检血尿怎么办