zoukankan      html  css  js  c++  java
  • HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

    二分图最大权值匹配问题。用KM算法。

    最小权值的时候把权值设置成相反数

      1 /*--------------------------------------------------------------------------------------*/
      2 
      3 #include <algorithm>
      4 #include <iostream>
      5 #include <cstring>
      6 #include <ctype.h>
      7 #include <cstdlib>
      8 #include <cstdio>
      9 #include <vector>
     10 #include <string>
     11 #include <queue>
     12 #include <stack>
     13 #include <cmath>
     14 #include <set>
     15 #include <map>
     16 
     17 //debug function for a N*M array
     18 #define debug_map(N,M,G) printf("
    ");for(int i=0;i<(N);i++)
     19 {for(int j=0;j<(M);j++){
     20 printf("%d",G[i][j]);}printf("
    ");}
     21 //debug function for int,float,double,etc.
     22 #define debug_var(X) cout<<#X"="<<X<<endl;
     23 #define LL long long
     24 const int INF = 0x3f3f3f3f;
     25 const LL LLINF = 0x3f3f3f3f3f3f3f3f;
     26 /*--------------------------------------------------------------------------------------*/
     27 using namespace std;
     28 
     29 int N,M,T;
     30 const int maxn = 310;
     31 int nx,ny;
     32 int g[maxn][maxn];
     33 int linker[maxn],lx[maxn],ly[maxn];
     34 int slack[maxn];
     35 bool visx[maxn],visy[maxn];
     36 bool DFS(int x)
     37 {
     38     visx[x] = true;
     39     for(int y=0;y<ny;y++)
     40     {
     41         if(visy[y]) continue;
     42         int tmp = lx[x] + ly[y] - g[x][y];
     43         if(tmp == 0)
     44         {
     45             visy[y] = true;
     46             if(linker[y] == -1 || DFS(linker[y]))
     47             {
     48                 linker[y] = x;
     49                 return true;
     50             }
     51         }
     52         else if(slack[y] > tmp) slack[y] = tmp;
     53     }
     54     return false;
     55 }
     56 int KM()
     57 {
     58     memset(linker,-1,sizeof linker);
     59     memset(ly,0,sizeof ly);
     60     for(int i=0;i<nx;i++)
     61     {
     62         lx[i] = -INF;
     63         for(int j=0;j<ny;j++)   lx[i] = max(lx[i],g[i][j]);
     64     }
     65     for(int x=0;x<nx;x++)
     66     {
     67         for(int i=0;i<ny;i++) slack[i] = INF;
     68         while(true)
     69         {
     70             memset(visx,false,sizeof visx);
     71             memset(visy,false,sizeof visy);
     72             if(DFS(x)) break;
     73             int d = INF;
     74             for(int i=0;i<ny;i++) if(!visy[i] && d > slack[i]) d = slack[i];
     75             for(int i=0;i<nx;i++) if(visx[i]) lx[i] -= d;
     76             for(int i=0;i<ny;i++)
     77             {
     78                 if(visy[i]) ly[i] += d;
     79                 else slack[i] -= d;
     80             }
     81         }
     82     }
     83     int res = 0;
     84     for(int i=0;i<ny;i++) if(linker[i] != -1) res += g[linker[i]][i];
     85     return res;
     86 }
     87 int main()
     88 {
     89     while(~scanf("%d",&N))
     90     {
     91         for(int i=0;i<N;i++)
     92         {
     93             for(int j=0;j<N;j++)
     94             {
     95                 scanf("%d",&g[i][j]);
     96             }
     97         }
     98         nx = ny = N;
     99         printf("%d
    ",KM());
    100     }
    101 }
  • 相关阅读:
    大话设计模式学习笔记简单工厂 工厂 抽象工厂
    910月总序(update 1)
    虚表思考再探虚表布局
    深入浅出 (代码+图示)递归反转一个栈 lp 专题讲解
    算法导论笔记 二叉查找树问题
    叹 尽然把vs2008 crash!!
    关于二叉查找树的讨论+ 我的误解
    算法情景分析 二叉排序树 前驱+后缀 测试用列
    iBatis.NET中使用时间的注意事项
    JDK和JRE官方下载地址
  • 原文地址:https://www.cnblogs.com/helica/p/5829491.html
Copyright © 2011-2022 走看看