URAL 1076 Trash 【最大权匹配KM快速模板O(N^3)】
来源:互联网 发布:域名服务器dns 编辑:程序博客网 时间:2024/06/05 06:05
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1076
我的链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=19651#problem/H
1076. Trash
Memory Limit: 16 MB
题意:
你受聘于当地的垃圾处理公司任CEO,你的一项工作是处理引进的垃圾,以及分类垃圾以进行循环利用。每天,垃圾会有几个集装箱运来,每一个集装箱都包含几种垃圾。给定集装箱里垃圾的数目n,请找出最佳的途径去分类这些垃圾。分类垃圾即把每种垃圾分开装到不同的集装箱中。每个集装箱的容量都是无限的。搬动一个单位的垃圾需要耗费代价,从集装箱i到j是1(i≠j,否则代价为0),你必须把代价减到最小。
思路:
求最大权匹配的KM算法,只需把所有边的权值取相反数,求最大权匹配,结果再取相反数即可。
把垃圾筒作为点集u,垃圾总类作为点集v,建图w[i][j]表示把j类垃圾放入i 桶的代价。
分析:用前面的KM模板时间复杂度为O(N^4)容易超时。
前面的版本修改顶标:
枚举s和t中的每一个元素,根据定义计算最小值,每次修时间为O(N^2),总时间为O(N^4).
快速修改顶标法:
给t中的每个节点y定义松弛量。slack(y) = min{ l[x]+l[y]-w[x][y] }
则a变为a = min{ slack(y)| y in t`}
计算所有slack要O(N)时间。每次增广后最多修改N次顶标,所以每次增广后修改顶标总时间为O(N^2),程序总时间降为O(N^3).
//Accepted216 KB31 msC++1503 B2013-02-26 20:03:10#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=155;const int inf=1000;int w[maxn][maxn];int lx[maxn],ly[maxn]; //顶标 bool s[maxn],t[maxn];int match[maxn];int slack[maxn]; //点集v的松弛量 int n;bool hungary(int u){s[u] = true;for(int v=1;v<=n;v++){if(!t[v] && lx[u]+ly[v] == w[u][v]){t[v] = true;if(match[v]==-1 || hungary(match[v])){match[v]=u;return true;}}else if(slack[v] > lx[u]+ly[v]-w[u][v])//修改松弛量 slack[v] = lx[u]+ly[v]-w[u][v];}return false;}int KM(){int sum=0;memset(match,-1,sizeof(match));memset(ly,0,sizeof(ly));for(int i=1;i<=n;i++){lx[i]= -inf;for(int j=1;j<=n;j++)lx[i]=max(lx[i],w[i][j]);}for(int i=1;i<=n;i++){while(true){memset(s,false,sizeof(s));memset(t,false,sizeof(t));for(int j=1;j<=n;j++)slack[j]=inf;if(hungary(i)) break;else{int a=inf;for(int j=1;j<=n;j++)if(!t[j] && slack[j]<a)a=slack[j];for(int j=1;j<=n;j++){if(s[j]) lx[j]-=a;if(t[j]) ly[j]+=a;}}}}for(int i=1;i<=n;i++) sum+=w[match[i]][i];return sum; }int main(){int weight;while(scanf("%d",&n)!=EOF){for(int i=1;i<=n;i++){weight=0;for(int j=1;j<=n;j++){scanf("%d",&w[i][j]);weight+=w[i][j];}for(int j=1;j<=n;j++)w[i][j]=weight-w[i][j];}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)w[i][j] = -w[i][j];}printf("%d\n",-KM());}return 0;}
- URAL 1076 Trash 【最大权匹配KM快速模板O(N^3)】
- URAL 1076 Trash [最佳匹配KM]
- ural 1076 Trash 二分图最大权匹配(费用流实现)
- 最大权二分匹配—KM算法入门 && 模板
- hdu 2255 二分图最大权匹配 km算法模板
- 【二分图最大权匹配】【KM算法模板】
- 二分图最大权匹配--KM算法模板
- KM算法模板(二分图的最大权匹配)
- ural 1076 Trash 二分图KM
- KM算法O(n^3)模板 hdu2255
- 完备匹配下的最大权匹配-KM算法的一般模板
- 最大权匹配KM算法的理解
- 【二分图最大权匹配---KM算法】
- 【最大权二分匹配的KM算法】
- 最大权匹配算法(km)
- 二分图最大权匹配 (KM算法)
- 最大权匹配的KM算法
- 二分图最大权匹配-km算法
- “没有错误”本身就是一个错误
- hdu 1010
- 转 Servlet生命周期与工作原理
- Q2_棋盘上的距离做题总结
- Java泛型-类型擦除
- URAL 1076 Trash 【最大权匹配KM快速模板O(N^3)】
- Comparator与Comparable的区别
- jvm GC日志输出
- 商业模式的四个环节
- Firefox OS为何大受运营商青睐?
- 编译arm平台的strace
- 索引
- 创业失败都有一个通病:懒
- EditPlus中配置java运行环境