二分图带权匹配
来源:互联网 发布:网络女主播不雅视频 编辑:程序博客网 时间:2024/06/05 10:52
#include <cstdio>#include <memory.h>#include <algorithm> // 使用其中的 min 函数using namespace std;const int MAX = 405;int n; // X 的大小int weight [MAX] [MAX]; // X 到 Y 的映射(权重)int lx [MAX], ly [MAX],a[MAX],ans[MAX]; // 标号bool sx [MAX], sy [MAX]; // 是否被搜索过int match [MAX]; // Y(i) 与 X(match [i]) 匹配// 初始化权重void init (int size);// 从 X(u) 寻找增广道路,找到则返回 truebool path (int u);// 参数 maxsum 为 true ,返回最大权匹配,否则最小权匹配int bestmatch (bool maxsum = true);void init (int size){ // 根据实际情况,添加代码以初始化 n = size; int i,j,k,t; memset(weight,0,sizeof(weight)); for (i=1;i<=n;i++) scanf("%d",&a[i-1]); for (i=0;i<n;i++) { scanf("%d",&k); for (j=0;j<k;j++) { scanf("%d",&t); weight[i][t-1]=a[i]*a[i]; } }}bool path (int u){ sx [u] = true; for (int v = 0; v < n; v ++) if (!sy [v] && lx[u] + ly [v] == weight [u] [v]) { sy [v] = true; if (match [v] == -1 || path (match [v])) { match [v] = u; return true; } } return false;}int bestmatch (bool maxsum){ int i, j; if (!maxsum) { for (i = 0; i < n; i ++) for (j = 0; j < n; j ++) weight [i] [j] = -weight [i] [j]; } // 初始化标号 for (i = 0; i < n; i ++) { lx [i] = -0x1FFFFFFF; ly [i] = 0; for (j = 0; j < n; j ++) if (lx [i] < weight [i] [j]) lx [i] = weight [i] [j]; } memset (match, -1, sizeof (match)); for (int u = 0; u < n; u ++) while (1) { memset (sx, 0, sizeof (sx)); memset (sy, 0, sizeof (sy)); if (path (u)) break; // 修改标号 int dx = 0x7FFFFFFF; for (i = 0; i < n; i ++) if (sx [i]) for (j = 0; j < n; j ++) if(!sy [j]) dx = min (lx[i] + ly [j] - weight [i] [j], dx); for (i = 0; i < n; i ++) { if (sx [i]) lx [i] -= dx; if (sy [i]) ly [i] += dx; } } int sum = 0; for (i = 0; i < n; i ++) sum += weight [match [i]] [i]; if (!maxsum) { sum = -sum; for (i = 0; i < n; i ++) for (j = 0; j < n; j ++) weight [i] [j] = -weight [i] [j]; // 如果需要保持 weight [ ] [ ] 原来的值,这里需要将其还原 } return sum;}int main(){ int n,i; scanf ("%d", &n); init (n); int cost = bestmatch (true); //printf ("%d\n", cost); //for (i=0;i<n;i++) printf("%d ",match[i]+1); for (i=0;i<n;i++) if (weight[match[i]][i]==0) ans[match[i]]=0;else ans[match[i]]=i+1; for (i=0;i<n-1;i++) printf("%d ",ans[i]); printf("%d",ans[n-1]); return 0;}
0 0
- 二分图带权匹配问题
- 二分图带权匹配
- hdu3395 -- 二分图带权匹配
- 二分图带权匹配
- poj2195 二分图带权最小匹配
- 二分匹配
- 二分匹配
- 二分匹配
- 二分匹配
- 二分匹配
- 二分匹配
- 二分匹配
- 二分匹配
- 二分匹配
- 二分匹配
- 二分匹配
- 二分匹配
- 二分匹配
- HDU-1043 Eight(A*)
- maven 仓库
- java之集合Collection 3个例子
- 高级控件 Advanced Widgets :Using GIndexGroup and GindexCombo
- HDU 1029 Ignatius and the Princess IV【贪心】
- 二分图带权匹配
- 回溯法——八皇后问题
- 数学之美番外篇:平凡而又神奇的贝叶斯方法
- C语言 sscanf,sprintf函数 使用总结
- hdu1503 Advanced Fruits
- 点的旋转
- After Windows 10 upgrading deleting previous windows installation
- I/O多路复用详解(三)
- 动态创建标签