HDU 6346 整数规划 二分图匹配最优解

Posted mingsd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6346 整数规划 二分图匹配最优解相关的知识,希望对你有一定的参考价值。

整数规划

在xi 与 yi 之间建立一条边值为a[i][j]的边, 然后跑km算法 2分图最优匹配。

原来的km+hunger跑法T了, 拿了一个新的板子, 新的写法是将这原来的找新的最小的d放在了上一次的残留图上,从而减小复杂度, 但是个人还不是很理解为什么最小的d下一次出现的位置一定是这次出现的位置的对应的x的点。

 

复杂度:n3

代码:

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 const int inf = 0x3f3f3f3f;
 5 const LL INF = 0x3f3f3f3f3f3f3f3f;
 6 const int N = 210;
 7 int val[N][N];
 8 LL lx[N],ly[N];
 9 int linky[N];
10 LL pre[N];
11 bool vis[N];
12 bool visx[N],visy[N];
13 LL slack[N];
14 int n;
15 void bfs(int k)
16 {
17     LL px, py = 0,yy = 0, d;
18     memset(pre, 0, sizeof(LL) * (n+2));
19     memset(slack, inf, sizeof(LL) * (n+2));
20     linky[py]=k;
21     do{
22         px = linky[py],d = INF, vis[py] = 1;
23         for(int i = 1; i <= n; i++)
24             if(!vis[i]){
25                 if(slack[i] > lx[px] + ly[i] - val[px][i])
26                     slack[i] = lx[px] + ly[i] - val[px][i], pre[i] = py;
27                 if(slack[i] < d) d = slack[i], yy = i;
28             }
29         for(int i = 0; i <= n; i++)
30             if(vis[i]) lx[linky[i]] -= d, ly[i] += d;
31             else slack[i] -= d;
32         py = yy;
33     }while(linky[py]);
34     while(py) linky[py] = linky[pre[py]] , py=pre[py];
35 }
36 void KM()
37 {
38     memset(lx, 0, sizeof(int)*(n+2));
39     memset(ly, 0, sizeof(int)*(n+2));
40     memset(linky, 0, sizeof(int)*(n+2));
41     for(int i = 1; i <= n; i++)
42         memset(vis, 0, sizeof(bool)*(n+2)), bfs(i);
43 }
44 int main()
45 {
46     int T;
47     scanf("%d", &T);
48     for(int _i = 1; _i <= T; _i++){
49         scanf("%d", &n);
50         for(int i = 1; i <= n; i++){
51             for(int j = 1; j <= n; j++){
52                 scanf("%d", &val[i][j]);
53                 val[i][j] = -val[i][j];
54             }
55         }
56         KM();
57         LL ans = 0;
58         for(int i = 1; i <= n; ++i)
59             ans += lx[i] + ly[i];
60         printf("Case #%d: %I64d
", _i, -ans);
61     }
62     return 0;
63 }
View Code

 

以上是关于HDU 6346 整数规划 二分图匹配最优解的主要内容,如果未能解决你的问题,请参考以下文章

hdu 2255奔小康赚大钱 KM算法模板

用分支定界算法求解整数规划

hdu 5646 DZY Loves Partition 二分+数学分析+递推

混合整数线性规划

分治、贪心五大算法

HDU 5727 Necklace ( 2016多校二分图匹配 )