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\n", _i, -ans);
61     }
62     return 0;
63 }

原文地址:https://www.cnblogs.com/MingSD/p/9436476.html

时间: 2024-11-13 09:32:17

HDU 6346 整数规划 二分图匹配最优解的相关文章

MZL&#39;s City (hdu 5352 最小费用流 ||二分图匹配)

MZL's City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 719    Accepted Submission(s): 251 Problem Description MZL is an active girl who has her own country. Her big country has N cities num

hdu 5727 Necklace 二分图匹配

题目链接 给2*n个珠子, n<=9, n个阴n个阳. 然后将它们弄成一个环, 阴阳交替.现在给你m个关系, 每个关系给出a, b. 如果阳a和阴b挨着, 那么a就会变暗. 问你最小变暗几个阳. 我们求出阴的所有全排列, 是9!, 因为形成一个环. 所以可以想象成一个珠子是固定不变的, 剩下n-1个变, 所以就是8!. 然后对于每种情况, 就是我们熟悉的二分图匹配了. 对于两个阴珠之间的空隙, 如果阳珠可以放到这里就连一条边. 然后跑匈牙利匹配就可以了. 9!过不了... #include <

A - Fire Net - hdu 1045(二分图匹配)

题意:一个阵地可以向四周扫射,求出来最多能修多少个阵地,墙不可以被扫射透,阵地不能同行或者或者列(有墙隔着例外) 分析:很久以前就做过这道题..当时是练习深搜来着,不过时间复杂度比较高,现在再看突然发现原来可以用二分图匹配来做,时间soso的 ****************************************************************** #include<stdio.h>#include<string.h>#include<algorit

E - Swap - hdu 2819(简单二分图匹配)

题意:如果可以交换行列,问主对角线能不能全为1 分析:要想主对角线全为1很明显要有N个行列不想同的点就行了,可以用二分图匹配计算出来多能有几个.如果小与N就不能.输出要是对的就行,不必和答案一样 ************************************************************************ #include<stdio.h>#include<algorithm>#include<string.h>using namesp

HDU 6346 整数规划 (最佳完美匹配)

整数规划 Time Limit: 5500/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 435    Accepted Submission(s): 144 Problem Description 度度熊有一个可能是整数规划的问题: 给定 n×n 个整数 ai,j(1≤i,j≤n),要找出 2n 个整数 x1,x2,-,xn,y1,y2,-,yn 在满足 xi+y

D - 棋盘游戏 - HDU 1281(二分图匹配)

分析:先求出来最大匹配数,然后用匹配的点一个一个去除看看能否达到最大匹配,能的话就是关键点(很暴力啊),不过竟然才31ms ***************************************************************** #include<stdio.h>#include<string.h>#include<algorithm>using namespace std; const int MAXN = 105; bool G[MAXN]

hdu 1083 Courses(二分图匹配)

Courses Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4278    Accepted Submission(s): 2036 Problem Description Consider a group of N students and P courses. Each student visits zero, one or

F - Rain on your Parade - hdu 2389(二分图匹配,Hk算法)

题意:给一些人和一些伞的坐标,然后每个人都有一定的速度,还有多少时间就会下雨,问最多能有多少人可以拿到伞. 分析:题意很明确,可以用每个人和伞判断一下是否能够达到,如果能就建立一个联系.不过这道题的数据还是挺大的,第一次使用的匈牙利算法果断的TLE了,然后就百度了一下发现有一个 Hopcroft-Karp算法 不过这个算法网上描述的很少,而且都说的比较含糊不清,不过幸好搜到一个比较不错的课件,看了一上午总算有些明白怎么回事,以前是寻找一个增广路,这个是寻找所有的增广路,并且使用BFS进行分层,看

G - Oil Skimming - hdu 4185(二分图匹配)

题意:在大海里有一些石油 ‘#’表示石油, ‘.’表示水,有个人有一个工具可以回收这些石油,不过只能回收1*2大小的石油块,里面不能含有海水,要不就没办法使用了,求出来最多能回收多少块石油 分析:先把数据处理一下,给每一点石油都进行编号,然后查找一下四周联合是否能组成石油块,能的话就连接,因为一点有可能即在左边又在右边,所以最后的结果应该除去 2 ************************************************************************* #