HDU 2255 奔小康赚大钱(KM算法)

题目链接

最大的二分图带权匹配,KM算法模版题,抄的别人的。

 1 #include <iostream>

 2 #include <cstring>

 3 #include <string>

 4 #include <cstdio>

 5 using namespace std;

 6 #define N 301

 7 #define INF 0x7fffffff

 8 int mat[N][N];

 9 int match[N];

10 int inx[N],iny[N];

11 int lx[N],ly[N];

12 int n;

13 int dfs(int u)

14 {

15     int i;

16     inx[u] = 1;

17     for(i = 1;i <= n;i ++)

18     {

19         if(!iny[i]&&lx[u] + ly[i] == mat[u][i])

20         {

21             iny[i] = 1;

22             if(match[i] == -1||dfs(match[i]))

23             {

24                 match[i] = u;

25                 return 1;

26             }

27         }

28     }

29     return 0;

30 

31 }

32 void KM()

33 {

34     int i,j,k,temp;

35     memset(lx,0,sizeof(lx));

36     memset(ly,0,sizeof(ly));

37     for(i = 1;i <= n;i ++)

38     {

39         for(j = 1;j <= n;j ++)

40         lx[i] = max(mat[i][j],lx[i]);

41     }

42     for(i = 1;i <= n;i ++)

43     {

44         for(;;)

45         {

46             memset(inx,0,sizeof(inx));

47             memset(iny,0,sizeof(iny));

48             if(dfs(i))

49             break;

50             else

51             {

52                 temp = INF;

53                 for(j = 1;j <= n;j ++)

54                 {

55                     if(inx[j])

56                     {

57                         for(k = 1;k <= n;k ++)

58                         {

59                             if(!iny[k]&&temp > lx[j]+ly[k] - mat[j][k])

60                             temp = lx[j]+ly[k] - mat[j][k];

61                         }

62                     }

63                 }

64                 for(j = 1;j <= n;j ++)

65                 {

66                     if(inx[j])

67                     lx[j] -= temp;

68                     if(iny[j])

69                     ly[j] += temp;

70                 }

71             }

72         }

73     }

74 }

75 int main()

76 {

77     int i,j;

78     while(scanf("%d",&n)!=EOF)

79     {

80         memset(match,-1,sizeof(match));

81         for(i = 1;i <= n;i ++)

82         {

83             for(j = 1;j <= n;j ++)

84             {

85                 scanf("%d",&mat[i][j]);

86             }

87         }

88         KM();

89         int ans = 0;

90         for(i = 1;i <= n;i ++)

91         ans += mat[match[i]][i];

92         printf("%d\n",ans);

93     }

94     return 0;

95 }

 

你可能感兴趣的:(HDU)