hdu 2255 奔小康赚大钱

奔小康赚大钱

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2493    Accepted Submission(s): 1103


Problem Description
传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子。
这可是一件大事,关系到人民的住房问题啊。村里共有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
 

 

Source
 

 

Recommend
lcy   |   We have carefully selected several similar problems for you:  3360 1083 2444 1533 2426 
 
 1 //421MS    612K    1801 B    C++
 2 /*
 3     
 4     题意:
 5         中文.
 6     
 7     最优匹配:
 8         KM算法模板题. 
 9      
10 */
11 #include<stdio.h>
12 #include<string.h>
13 #define N 305 
14 #define inf 0x7fffffff
15 int match[N],lx[N],ly[N];
16 int slack[N]; //松弛量,每次找增广路时可修改的的最大值 
17 int visx[N],visy[N],w[N][N];
18 int n;
19 inline int Min(int a,int b)
20 {
21     return a<b?a:b;
22 }
23 int dfs(int x)
24 {
25     visx[x]=1;
26     for(int i=1;i<=n;i++){
27         if(visy[i]) continue;
28         //int temp=lx[x]+ly[i]-w[x][i];
29         if(w[x][i]==lx[x]+ly[i]){
30             visy[i]=1;
31             if(match[i]==-1 || dfs(match[i])){
32                 match[i]=x;
33                 return 1;
34             }
35         }else slack[i]=Min(slack[i],lx[x]+ly[i]-w[x][i]);
36     }
37     return 0;
38 }
39 int km()
40 {
41     memset(match,-1,sizeof(match));
42     memset(ly,0,sizeof(ly));  //初始化ly 
43     for(int i=1;i<=n;i++){    //初始化lx 
44         lx[i]=-inf;
45         for(int j=1;j<=n;j++)
46             if(w[i][j]>lx[i]) 
47                 lx[i]=w[i][j];
48     }                          
49     for(int i=1;i<=n;i++){  //匹配n个顶点 
50         for(int j=1;j<=n;j++)
51             slack[j]=inf;
52         while(1){
53             memset(visx,0,sizeof(visx));
54             memset(visy,0,sizeof(visy));
55             if(dfs(i)) break; //匹配成功 
56             int d=inf;
57             for(int j=1;j<=n;j++)  //最小改变量 
58                 if(!visy[j] && d>slack[j]) 
59                     d=slack[j];
60             for(int j=1;j<=n;j++){ 
61                 if(visx[j]) lx[j]-=d;
62                 if(visy[j]) ly[j]+=d;
63                 else slack[j]-=d;
64             }
65         }
66     }
67     int res=0;
68     for(int i=1;i<=n;i++)
69         if(match[i]>-1) res+=w[match[i]][i];
70     return res;
71 }
72 int main(void)
73 {
74     while(scanf("%d",&n)!=EOF)
75     {
76         for(int i=1;i<=n;i++)
77             for(int j=1;j<=n;j++)
78                 scanf("%d",&w[i][j]);
79         printf("%d\n",km());
80     }
81     return 0;
82 }
posted @ 2013-11-04 19:57  heaventouch  阅读(162)  评论(0)    收藏  举报