zoukankan      html  css  js  c++  java
  • HDU 2426 Interesting Housing Problem(二分图最佳匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=2426

    题意:
    每n个学生和m个房间,现在要为每个学生安排一个房间居住,每个学生对于一些房间有一些满意度,如果满意度为负就说明该学生不喜欢住在这房间。现在问如何安排可以使所有学生的满意度总和最大。(不能将学生安排到他不喜欢的房间或者他没有评价的房间)

    思路:

    二分图的最佳匹配,注意题目的要求即可。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 using namespace std;
      5 const int maxn = 500+5;
      6 const int INF = 0x3f3f3f3f;
      7 
      8 int n, m, k;
      9 int g[maxn][maxn];
     10 int lx[maxn], ly[maxn];
     11 bool S[maxn], T[maxn];  //记录左右两边节点是否已匹配
     12 int match[maxn];
     13 int slack[maxn];   //差值
     14 
     15 bool dfs(int i)
     16 {
     17     S[i] = true;
     18     for (int j = 1; j <= m; ++j)
     19     {
     20         if (T[j]) continue;   //每一轮匹配,右边节点只能一次
     21         int gap = lx[i] + ly[j] - g[i][j];
     22         if (gap == 0)   //如果符合要求
     23         {
     24             T[j] = true;
     25             if (match[j] == -1 || dfs( match[j] ))
     26             {
     27                 match[j] = i;
     28                 return true;
     29             }
     30         }
     31         else slack[j] = min(slack[j], gap);
     32     }
     33     return false;
     34 }
     35 
     36 int KM()
     37 {
     38     memset(match, -1, sizeof match);
     39     memset(ly, 0, sizeof ly);   //初始化ly为0
     40     for (int i = 1; i<=n; i++)  //初始化lx[i]为该节点所有边中的最大权值
     41     {
     42         lx[i] = g[i][1];
     43         for (int j = 2; j<=m; j++)
     44             lx[i] = max(lx[i], g[i][j]);
     45     }
     46     for (int i=1; i<=n; i++)    //尝试为每个节点匹配节点
     47     {
     48         memset(slack,INF,sizeof(slack));    //因为要取最小值,初始化为无穷大
     49         while (true) {
     50             memset(S, false, sizeof S);   //记录每轮匹配中左右节点是否被尝试匹配过
     51             memset(T, false, sizeof T);
     52             if (dfs(i)) break;
     53             int d = INF;
     54             for (int j=1; j<=m; j++)
     55                 if (!T[j]) d = min(d, slack[j]);
     56             for (int j=1; j<=n; ++j)
     57                 if (S[j]) lx[j] -= d;
     58             for(int j=1;j<=m;j++)
     59             {
     60                 if (T[j]) ly[j] += d;
     61                 else slack[j] -= d;
     62             }
     63         }
     64     }
     65 
     66     int result = 0,flag=0;
     67     for(int i = 1; i <=m; i++){
     68         if(match[i]==-1||g[match[i]][i]==-INF)
     69             continue;
     70       if(match[i]>-1){
     71         result += g[match[i]][i];
     72         flag++;
     73       }
     74     }
     75     if(flag<n) result=-1;
     76     return result;
     77 
     78 }
     79 
     80 int main()
     81 {
     82     //freopen("in.txt","r",stdin);
     83     int cas = 0;
     84     while(~scanf("%d%d%d",&n,&m,&k))
     85     {
     86         if(n>m)
     87         {
     88             printf("Case %d: %d
    ", ++cas, -1);
     89             continue;
     90         }
     91         for(int i=1;i<=n;i++)
     92         for(int j=1;j<=m;j++)
     93             g[i][j] = -INF;
     94         for(int i=0;i<k;i++)
     95         {
     96             int u,v,w;
     97             scanf("%d%d%d",&u,&v,&w);
     98             u++; v++;
     99             if(w>=0) g[u][v] = w;
    100         }
    101         int ans = KM();
    102         printf("Case %d: %d
    ", ++cas, ans);
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    Azure HPC Pack Cluster添加辅助节点
    Azure HPC Pack 辅助节点模板配置
    Azure HPC Pack配置管理系列(PART6)
    Windows HPC Pack 2012 R2配置
    Azure HPC Pack 节点提升成域控制器
    Azure HPC Pack VM 节点创建和配置
    Azure HPC Pack 部署必要条件准备
    Azure HPC Pack 基础拓扑概述
    Azure VM 性能计数器配置
    Maven私仓配置
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/9291038.html
Copyright © 2011-2022 走看看