HDU2255二分匹配最大权值
2017-08-04 20:21
375 查看
传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子。
这可是一件大事,关系到人民的住房问题啊。村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子。
另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出10万,对第2间出2万,对第3间出20万.(当然是在他们的经济范围内).现在这个问题就是村领导怎样分配房子才能使收入最大.(村民即使有钱购买一间房子但不一定能买到,要看村领导分配的).
Input输入数据包含多组测试用例,每组数据的第一行输入n,表示房子的数量(也是老百姓家的数量),接下来有n行,每行n个数表示第i个村名对第j间房出的价格(n<=300)。
Output请对每组数据输出最大的收入值,每组的输出占一行。
Sample Input
Sample Output
123
一道二分匹配求最大权的模板题:
这可是一件大事,关系到人民的住房问题啊。村里共有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
一道二分匹配求最大权的模板题:
#include<stdio.h> #include<string.h> #include<math.h> #define LL long long template<class T> LL max(T a,T b) { return a>b?a:b; } template<class T> LL min(T a, T b) { return a<b?a:b; } const int MAX=305; const LL INF=1e9+5; LL nx,ny; //二部图两个部分的大小 int linker[MAX]; LL map[MAX][MAX]; LL lx[MAX],ly[MAX]; //两个部分的标记数组 int slack[MAX]; bool visy[MAX],visx[MAX]; //两个dfs标记 bool Dfs(int u) //匈牙利匹配 { visx[u]=1; for(int v=1;v<=ny;v++) { LL temp=lx[u]+ly[v]-map[u][v]; if(!visy[v]&&temp==0) //连通边且没走过 { visy[v]=1; if(linker[v]==-1||Dfs(linker[v])) { linker[v]=u; return 1; } } else if(temp!=0) { if(slack[v]>temp) slack[v]=temp; } } return 0; } LL Find() { memset(linker,-1,sizeof(linker)) ; memset(ly,0,sizeof(ly)); //初始化定点标记 for(int i=1;i<=nx;i++) { lx[i]=-INF; for(int j=1;j<=ny;j++) { if(map[i][j]>lx[i]) lx[i]=map[i][j]; } } for(int i=1;i<=nx;i++) { for(int j=1;j<=ny;j++) slack[j]=INF; while(true) { memset(visy,false,sizeof(visy)); memset(visx,false,sizeof(visx)); if(Dfs(i)) break; //对于每一个点去找匹配(最后形成完美匹配) LL d=INF; //找到最大扩展边 for(int j=1;j<=ny;j++) if(!visy[j]) { if(d>slack[j]) d=slack[j]; } for(int j=1;j<=nx;j++) //更新定点 if(visx[j]) lx[j]-=d; for(int j=1;j<=ny;j++) { if(visy[j]) ly[j]+=d; else slack[j]-=d; } } } LL sum=0; //求和 for(int i=1;i<=ny;i++) { if(linker[i]) sum+=map[linker[i]][i]; } return sum; } int main() { LL n; while(scanf("%lld",&n)!=EOF) { memset(map,0,sizeof(map)); LL v; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%lld",&v); map[i][j]=v; } nx=ny=n; printf("%lld\n",Find()); } return 0; }
相关文章推荐
- hdu 2255二分图最大权值匹配的KM 算法
- hdu 2853 Assignment(最大权值匹配)
- HDU-2255 奔小康赚大钱 最大权值匹配
- HDU-3718 Similarity 最大权值匹配
- Hdu 3395 【最大权值匹配】.cpp
- hdu 2426 Interesting Housing Problem(最大权值匹配)
- HDU-2853 Assignment 最大权值匹配+简直是太神了
- hdu 1853 Cyclic Tour 最大权值匹配 全部点连成环的最小边权和
- HDU-2426 Interesting Housing Problem 最大权值匹配-不能完成匹配的处理
- HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法
- HDU 2255 KM算法 二分图最大权值匹配
- hdu 1853 Cyclic Tour 最大权值匹配 所有点连成环的最小边权和
- HDU 2255-奔小康赚大钱(Kuhn-Munkras算法/KM算法-完备匹配下的最大权匹配)
- hdu 1068 二分图的最大匹配匈牙利算法
- hdu 2063 二分图—最大匹配
- HDU 1507 Uncle Tom's Inherited Land(黑白棋盘最大匹配)
- HDU 2063 过山车 (最大匹配,匈牙利算法)
- HDU 2444 The Accomodation of Students 二分图判定+最大匹配
- hdu 1281 棋盘游戏 (二分图最大匹配)
- hdu 3367 Pseudoforest 最大权值和伪森林