POJ 3686 The Windy's【最小权匹配(神建图啊)】

大意:有n个任务m个机器,告诉你n*m的矩阵表示每个任务在每个机器上完成需要的时间

问所有任务完成的总时间最少?(比如第一个任务在第一分钟完成第二个任务在第二分钟完成   则总时间为1 + 2 = 3

分析:

该题自己做的时候没有思路

后来在网上搜题解,感觉建图真是太厉害了

假设最优情况下,个个任务需要的时间分别为a1, a2, a3, ……,an

那么总时间t = n * a1 + (n - 1) * a2 + ……+ 2 * an - 1 + an

也就是说只需要考虑系数就可以了

我们先假设只有一台机器

那么也就是为每个任务的时间选择一个不同的系数

也就是从每个任务向该机器建n条边分别表示系数  边权值为k*cost即可

扩展为m台机器  只要把每个机器拆成n个点就可以了~~

代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <vector>
  5 using namespace std;
  6
  7 const int maxn = 55;
  8 const int INF = 1000000000;
  9
 10 int Sx[maxn], Sy[maxn * maxn];
 11 int Lx[maxn], Ly[maxn * maxn];
 12 int Link[maxn * maxn];
 13 int Lix[maxn];
 14 int W[maxn][maxn * maxn];
 15 int n, m;
 16
 17 bool Find(int i) {
 18     Sx[i] = true;
 19     for(int j = 1; j <= m; j++) {
 20         if(!Sy[j] && Lx[i] + Ly[j] == W[i][j] ) {
 21             Sy[j] = true;
 22             if(Link[j] == 0 || Find(Link[j])) {
 23                 Lix[i] = j;
 24                 Link[j] = i;
 25                 return true;
 26             }
 27         }
 28     }
 29     return false;
 30 }
 31
 32 int KM() {
 33     for(int i = 1; i <= n; i++) {
 34         Lx[i] = - INF;
 35         for(int j = 1; j <= m; j++) {
 36             Lx[i] = max(Lx[i], W[i][j]);
 37         }
 38     }
 39     memset(Ly, 0, sizeof(Ly));
 40     memset(Link, 0, sizeof(Link));
 41     for(int v = 1; v <= n; v++) {
 42         memset(Sx, 0, sizeof(Sx));
 43         memset(Sy, 0, sizeof(Sy));
 44         while(1) {
 45             if(Find(v)) break;
 46             int dmin = INF;
 47             for(int i = 1; i <= n; i++) {
 48                 if(Sx[i]) {
 49                     for(int j = 1; j <= m; j++) {
 50                         if(!Sy[j] && Lx[i] + Ly[j] - W[i][j] < dmin) {
 51                             dmin = Lx[i] + Ly[j] - W[i][j];
 52                         }
 53                     }
 54                 }
 55             }
 56             for(int i = 1; i <= n; i++) {
 57                 if(Sx[i]) {
 58                     Lx[i] -= dmin;
 59                     Sx[i] = 0;
 60                 }
 61             }
 62             for(int i = 1; i <= m; i++) {
 63                 if(Sy[i]) {
 64                     Ly[i] += dmin;
 65                     Sy[i] = 0;
 66                 }
 67             }
 68         }
 69     }
 70     int sum = 0;
 71     for(int i = 1; i <= n; i++) {
 72         sum += W[i][Lix[i]];
 73     }
 74     return sum;
 75 }
 76
 77 int mat[maxn][maxn];
 78 int main() {
 79     int t;
 80     scanf("%d",&t);
 81     while(t--) {
 82         scanf("%d %d",&n, &m);
 83         for(int i = 1; i <= n; i++) {
 84             for(int j = 1; j <= m; j++) {
 85                 scanf("%d",&mat[i][j]);
 86             }
 87         }
 88         for(int k = 1; k <= n; k++) {
 89             for(int i = 1; i <= m; i++) {
 90                 for(int j = 1; j <= n; j++) {
 91                     W[k][(i - 1) * n + j] = - mat[k][i] * j;
 92                 }
 93             }
 94         }
 95         m = n * m;
 96         int ans1 = -KM();
 97         double ans = ans1 * 1.0 / n;
 98         printf("%.6f\n",ans);
 99     }
100     return 0;
101 }

POJ 3686 The Windy's【最小权匹配(神建图啊)】

时间: 2024-08-27 12:55:44

POJ 3686 The Windy's【最小权匹配(神建图啊)】的相关文章

POJ 3686 The Windy&#39;s 最小权值匹配

点击打开链接 The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 3788   Accepted: 1630 Description The Windy's is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receives N orders for toys.

POJ 3686.The Windy&#39;s 最小费用最大流

The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5477   Accepted: 2285 Description The Windy's is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receives N orders for toys. The ma

poj 2195 Going Home 二分图最小权匹配KM算法

题意: 有n个人要回到n间房子里,每间房子只允许一个人,求n个人要走的最小距离和. 分析: 裸的二分图最小权匹配,KM搞之. 代码: //poj 2195 //sep9 #include <iostream> using namespace std; const int maxN=128; char g[maxN][maxN]; int mx[maxN],my[maxN],hx[maxN],hy[maxN]; int w[maxN][maxN]; int lx[maxN],ly[maxN],l

[ACM] POJ 3686 The Windy&#39;s (二分图最小权匹配,KM算法,特殊建图)

The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4158   Accepted: 1777 Description The Windy's is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receivesN orders for toys. The man

poj 3686 The Windy&#39;s 二分图最小权和匹配KM

题意: 给n个玩具和m家工厂,每个玩具只能在一家工厂加工,给出每个玩具在每家工厂需要的加工时间,求这n个玩具完成时间平均值的最小值. 分析: 求最小和容易联系到二分图的最小权和匹配,这题的问题是n与m的大小关系是不确定的,也是就是说可能会有多个玩具到同一家工厂里加工的情况,这似乎与匹配的定义相矛盾.但仔细一想,如果多个玩具在同一工厂加工,他们的完成时间肯定是不一样的,所以讲w[i][j]=z 拆成w[i][0*m+j]=z,w[i][1*m+j]=2*z,w[i][2*m+j]=3*z.....

POJ 2195 二分图最小权匹配KM算法

本来是打算昨天晚上写的, 昨天网速渣的连CSDN都进不去,没办法 只能现在来写了 先写写对KM算法的理解,KM算法是对每个点设置一个顶标,只有当边长等于两边点的顶标之和的时候才进行增广,这样就能保证得到的一定是最大权匹配. 如果找不到匹配的时候就对交替路中X集合的顶标减少一个d Y集合的顶标增加一个d. 这样两个点都在交替路中的时候x[i]+y[i]的和不边 X在 Y不在的时候x[i]+y[i]减少,可能就会为图增加一对匹配. X不在Y在的时候x[i]+y[i]增加, 原来不在现在依然不在其中.

【POJ 2400】 Supervisor, Supervisee(KM求最小权匹配)

[POJ 2400] Supervisor, Supervisee(KM求最小权匹配) Supervisor, Supervisee Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2538   Accepted: 719 Description Suppose some supervisors each get to hire a new person for their department. There are N

【POJ 2195】 Going Home(KM算法求最小权匹配)

[POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20303   Accepted: 10297 Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit ste

poj - 3686 The Windy&#39;s (KM算法)

题意:n个订单和m个生产车间,每个订单在不同的车间生产所需要的时间不一样,并且每个订单只能在同一个车间中完成,直到这个车间完成这个订单就可以生产下一个订单.现在需要求完成n个订单的平均时间最少是多少.(每个订单的单独时间之和/n,包括等待时间). 主要是建图,考虑第i个订单在第j个车间倒数第k个被生产,那么第i个订单在第j个区间所花费的时间为k*mat[i][j]. 每个区间最多生产n个订单,那么就可以把n*m的图转化成n*(n*m)的图进而用km算法求最小权值. 所以把每个权值取反进而求最大权