URAL 1076 Trash 【最大权匹配KM快速模板O(N^3)】
2013-02-26 20:24
411 查看
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1076
我的链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=19651#problem/H
Time Limit: 1.0 second
Memory Limit: 16 MB
Description
You were just hired as CEO of the local junkyard.One of your jobs is dealing with the incoming trash and sorting it for recycling.The trash comes every day in N containers and each of these containers contains certain
amount of each of the N types of trash. Given the amount of trash in the containers find the optimal way to sort the trash. Sorting the trash means putting every type of trash in separate container. Each of the given containers has infinite capacity.
The effort for moving one unit of trash from container i to j is 1 if i ≠ j otherwise it is 0.You are to minimize the total effort.
Input
The first line contains the number N (1 ≤ N ≤ 150), the rest of the input contains the descriptions of the containers.The (1 + i)-th line contains the description of the i-th container the j-th
amount (0 ≤ amount ≤ 100) on this line denotes the amount of the j-th type of trash in the i-th container.
Output
You should write the minimal effort that is required for sorting the trash.
Sample Input
题意:
你受聘于当地的垃圾处理公司任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).
我的链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=19651#problem/H
1076. Trash
Time Limit: 1.0 secondMemory Limit: 16 MB
Description
You were just hired as CEO of the local junkyard.One of your jobs is dealing with the incoming trash and sorting it for recycling.The trash comes every day in N containers and each of these containers contains certain
amount of each of the N types of trash. Given the amount of trash in the containers find the optimal way to sort the trash. Sorting the trash means putting every type of trash in separate container. Each of the given containers has infinite capacity.
The effort for moving one unit of trash from container i to j is 1 if i ≠ j otherwise it is 0.You are to minimize the total effort.
Input
The first line contains the number N (1 ≤ N ≤ 150), the rest of the input contains the descriptions of the containers.The (1 + i)-th line contains the description of the i-th container the j-th
amount (0 ≤ amount ≤ 100) on this line denotes the amount of the j-th type of trash in the i-th container.
Output
You should write the minimal effort that is required for sorting the trash.
Sample Input
input | output |
---|---|
4 62 41 86 94 73 58 11 12 69 93 89 88 81 40 69 13 | 650 |
你受聘于当地的垃圾处理公司任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).
//Accepted 216 KB 31 ms C++ 1503 B 2013-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 二分图最大权匹配(费用流实现)
- URAL 1076 Trash [最佳匹配KM]
- URAL 1076 Trash Trash(最大权匹配)
- KM(带权最大二分匹配) 模板
- ural 1076 KM求最小权匹配
- URAL 1099 Work scheduling 一般图的最大匹配 带花树算法(模板)
- ural 1076 Trash 二分图KM
- 二分图最大权最小权完美匹配模板KM
- One fihgt one hdu 2813 map+二分图最优匹配+KM快速模板
- HDU 3523 Image copy detection(KM最大匹配)
- 求二分图最大匹配——匈牙利算法模板。
- URAL 1099. Work Scheduling 一般图匹配模板题
- 匈牙利算法,二分图最大匹配、多重匹配模板
- [模板]带花树算法(一般图最大匹配)
- luogu3386【模板】二分图最大匹配
- hdu 2603 过山车 最大匹配,匈牙利算法模板(易理解)
- hdu 2255二分图最大权值匹配的KM 算法
- 最大匹配之匈牙利算法模板。。
- [模板]二分图最大权匹配