zoukankan      html  css  js  c++  java
  • 【KM算法】HDU2255-奔小康赚大钱

    KM算法的裸体。O(n^4)的模板,实际上在增广路径的时候依然有冗余,可以用bfs优化到O(n^3)。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <algorithm>
     7 using namespace std;
     8 const int MAXN=400+5;
     9 const int INF=0x7fffffff;
    10 int n,m;
    11 int w[MAXN][MAXN];
    12 int x[MAXN],y[MAXN]; 
    13 int visx[MAXN],visy[MAXN],slack[MAXN];
    14 int lk[MAXN];
    15 
    16 int dfs(int u)
    17 {
    18     visx[u]=1;
    19     for (int i=1;i<=n;i++)
    20     {
    21         int wt=x[u]+y[i]-w[u][i];
    22         if (!visy[i] && wt==0)
    23         {
    24             visy[i]=1;
    25             if (lk[i]==-1 || dfs(lk[i]))
    26             {
    27                 lk[i]=u;
    28                 return 1;
    29             }
    30         }
    31         else if (slack[i]>wt) slack[i]=wt;
    32     }
    33     return 0;
    34 }
    35 
    36 int KM()
    37 {
    38     memset(lk,-1,sizeof(lk));
    39     for (int i=1;i<=n;i++)
    40     {
    41         y[i]=0;
    42         x[i]=-INF;
    43         for (int j=1;j<=n;j++) x[i]=max(x[i],w[i][j]);
    44     }
    45     for (int i=1;i<=n;i++)
    46     {
    47         memset(visx,0,sizeof(visx));
    48         memset(visy,0,sizeof(visy));
    49         memset(slack,127,sizeof(slack)); 
    50         while (!dfs(i))
    51         {
    52             int delta=INF;
    53             for (int j=1;j<=n;j++)
    54                 if (!visy[j] && slack[j]<delta) delta=slack[j];
    55             for (int j=1;j<=n;j++) 
    56             {
    57                 if (visx[j]) 
    58                 {
    59                     x[j]-=delta;
    60                     visx[j]=0;
    61                 }
    62                 if (visy[j]) 
    63                 {
    64                     y[j]+=delta;
    65                     visy[j]=0;
    66                 }
    67             }
    68         } 
    69     }
    70     int ret=0;
    71     for (int i=1;i<=n;i++) ret+=x[i]+y[i];
    72     return ret;
    73 }
    74 
    75 void init()
    76 {
    77     memset(w,0,sizeof(w));
    78     for (int i=1;i<=n;i++)
    79     {
    80         for (int j=1;j<=n;j++) 
    81             scanf("%d",&w[i][j]);
    82     }
    83 }
    84 
    85 int main()
    86 {
    87     while (~scanf("%d",&n))
    88     {
    89         init();
    90         printf("%d
    ",KM());
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    mac 卸载 node并重新安装
    最小的Django应用
    Python如何实现文本转语音
    Python语言库pyttsx3
    大数据资料
    剑指offer(29)最小的K个数
    剑指offer(28)数组中出现次数超过一半的数
    剑指offer(27)字符串的排列
    剑指offer(26)二叉搜索树与双向链表
    JS、JAVA刷题和C刷题的一个很重要的区别
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5352199.html
Copyright © 2011-2022 走看看