• HDU 3315 KM My Brute


    参考题解

    二分图的最优匹配。图很容易建立。再处理相似度的时候。把每个权值扩大100倍。然后再对i==j时 特殊标记。使他们的权值再++1。后面选择的时候就很容易挑出。按原匹配

    匹配的个数。 100*(double)(res%100)/n。即可得到第二问。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <vector>
      6 #include <queue>
      7 using namespace std;
      8 
      9 const int maxn = 100;
     10 const int INF = 0x3f3f3f3f;
     11 
     12 int n;
     13 
     14 int V[maxn], H[maxn], P[maxn], A[maxn], B[maxn];
     15 
     16 // KM algorithm
     17 int W[maxn][maxn], lft[maxn];
     18 int slack[maxn];
     19 int Lx[maxn], Ly[maxn];
     20 bool S[maxn], T[maxn];
     21 
     22 int inline divide(int a, int b) { int ans = a / b; if(a % b) ans++; return ans; }
     23 
     24 bool match(int u)
     25 {
     26     S[u] = true;
     27     for(int v = 1; v <= n; v++) if(!T[v])
     28     {
     29         int t = Lx[u] + Ly[v] - W[u][v];
     30         if(t == 0)
     31         {
     32             T[v] = true;
     33             if(!lft[v] || match(lft[v]))
     34             {
     35                 lft[v] = u;
     36                 return true;
     37             }
     38         }
     39         else slack[v] = min(slack[v], t);
     40     }
     41 
     42     return false;
     43 }
     44 
     45 void update()
     46 {
     47     int a = INF;
     48     for(int i = 1; i <= n; i++) if(!T[i]) a = min(a, slack[i]);
     49     for(int i = 1; i <= n; i++)
     50     {
     51         if(S[i]) Lx[i] -= a;
     52 
     53         if(T[i]) Ly[i] += a;
     54         else slack[i] -= a;
     55     }
     56 }
     57 
     58 void KM()
     59 {
     60     memset(Ly, 0, sizeof(Ly));
     61     memset(lft, 0, sizeof(lft));
     62     for(int i = 1; i <= n; i++) Lx[i] = -INF;
     63     for(int i = 1; i <= n; i++)
     64         for(int j = 1; j <= n; j++) Lx[i] = max(Lx[i], W[i][j]);
     65 
     66     for(int i = 1; i <= n; i++)
     67     {
     68         memset(slack, 0x3f, sizeof(slack));
     69         for(;;)
     70         {
     71             memset(S, false, sizeof(S));
     72             memset(T, false, sizeof(T));
     73             if(match(i)) break;
     74             update();
     75         }
     76     }
     77 }
     78 
     79 int main()
     80 {
     81     while(scanf("%d", &n) == 1 && n)
     82     {
     83         for(int i = 1; i <= n; i++) scanf("%d", V + i);
     84         for(int i = 1; i <= n; i++) scanf("%d", H + i);
     85         for(int i = 1; i <= n; i++) scanf("%d", P + i);
     86         for(int i = 1; i <= n; i++) scanf("%d", A + i);
     87         for(int i = 1; i <= n; i++) scanf("%d", B + i);
     88 
     89         //build graph
     90         for(int i = 1; i <= n; i++)
     91             for(int j = 1; j <= n; j++)
     92             {
     93                 int score = V[i] * 100;
     94                 int round1 = divide(P[j], A[i]);
     95                 int round2 = divide(H[i], B[j]);
     96                 if(round1 > round2) score = -score;
     97                 if(i == j) score++;
     98                 W[i][j] = score;
     99             }
    100 
    101         KM();
    102 
    103         int ans = 0;
    104         for(int i = 1; i <= n; i++) ans += W[lft[i]][i];
    105 
    106         if(ans < 0)
    107         {
    108             puts("Oh, I lose my dear seaco!");
    109             continue;
    110         }
    111 
    112         printf("%d ", ans / 100);
    113         printf("%.3f%%
    ", 100.0 * (ans % 100) / n);
    114     }
    115 
    116     return 0;
    117 }
    代码君
  • 相关阅读:
    Golang判断文件/文件夹是否存在
    Golang将一个文件中的内容写入到另一个文件里
    Golang打开已存在的文件并覆盖其内容
    Golang打开文件并写入
    【正则】day01
    【正则】day02
    【day09】PHP
    【day08】PHP
    转换函数
    变量作用域
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4802056.html
Copyright © 2020-2023  润新知