• 奔小康赚大钱


    奔小康赚大钱

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

    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
     
    题意:每家对每间房子有一个费用,怎么分配可以让总的费用最大。
    KM
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 
     6 using namespace std;
     7 
     8 #define N 330
     9 #define INF 0xfffffff
    10 
    11 int n, s[N];
    12 int lx[N], ly[N], maps[N][N], used[N], visx[N], visy[N];
    13 
    14 int found(int u)
    15 {
    16     visx[u] = true;
    17     for(int i = 1; i <= n; i++)
    18     {
    19         if(!visy[i] && lx[u] + ly[i] == maps[u][i])
    20         {
    21             visy[i] = 1;
    22             if(!used[i] || found(used[i]))
    23             {
    24                 used[i] = u;
    25                 return true;
    26             }
    27         }
    28         else
    29             s[i] = min(s[i], lx[u]+ly[i]-maps[u][i]);
    30     }
    31     return false;
    32 }
    33 
    34 int KM()
    35 {
    36     memset(used, 0, sizeof(used));
    37     memset(lx, 0, sizeof(lx));
    38     memset(ly, 0, sizeof(ly));
    39 
    40     for(int i = 1; i <= n; i++)
    41         for(int j = 1; j <= n; j++)
    42         lx[i] = max(lx[i], maps[i][j]);   // 每个lx存的是可以的最大值,ly是0,相加就是自己所投的资金最大值。
    43     for(int i = 1; i <= n; i++)
    44     {
    45         for(int j = 1; j <= n; j++)
    46             s[j] = INF;
    47         while(1)
    48         {
    49             memset(visx, 0, sizeof(visx));
    50             memset(visy, 0, sizeof(visy));
    51 
    52             if(found(i)) 
    53                 break;
    54             int d = INF;
    55             for(int j = 1; j <= n; j++)
    56                 if(!visy[j])
    57                     d = min(d, s[j]);   // 如果找不到最大值匹配,就找需要减得最小值,让该匹配的减去最小值完成最大匹配
    58             for(int j = 1; j <= n; j++)
    59             {
    60                 if(visx[j])
    61                     lx[j] -= d;
    62                 if(visy[j])
    63                     ly[j] += d;
    64             }
    65         }
    66     }
    67     int ans = 0;
    68     for(int i = 1; i <= n; i++)
    69         ans += maps[used[i]][i];
    70     return ans;
    71 }
    72 
    73 int main()
    74 {
    75     while(~scanf("%d", &n))
    76     {
    77         for(int i = 1; i <= n; i++)
    78         {
    79             for(int j = 1; j <= n; j++)
    80             {
    81                 scanf("%d", &maps[i][j]);
    82             }
    83         }
    84         printf("%d
    ", KM());
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    关于项目中 "不能创建大小为 8190 的行,该大小大于所允许的最大行大小 8060 "的处理
    sql 使用with 递归
    ssh,安全验证的级别(来自BD百科)
    Windows系统自带路由命令Route add,解决双网卡网络流向问题
    irreversiblecipher和cipher区别(华为交换机)
    Centos7重置root密码(20220527 02:03测试可用)
    2022中级财务管理相关公式的总结
    移动端软键盘顶出nav
    React.Component生命周期
    Axure 9 单选效果
  • 原文地址:https://www.cnblogs.com/Tinamei/p/4792252.html
Copyright © 2020-2023  润新知