zoukankan      html  css  js  c++  java
  • hdu 2426 Interesting Housing Problem 最大权匹配KM算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2426

    For any school, it is hard to find a feasible accommodation plan with every student assigned to a suitable apartment while keeping everyone happy, let alone an optimal one. Recently the president of University ABC, Peterson, is facing a similar problem. While Peterson does not like the idea of delegating the task directly to the class advisors as so many other schools are doing, he still wants to design a creative plan such that no student is assigned to a room he/she dislikes, and the overall quality of the plan should be maximized. Nevertheless, Peterson does not know how this task could be accomplished, so he asks you to solve this so-called "interesting" problem for him.
    Suppose that there are N students and M rooms. Each student is asked to rate some rooms (not necessarily all M rooms) by stating how he/she likes the room. The rating can be represented as an integer, positive value meaning that the student consider the room to be of good quality, zero indicating neutral, or negative implying that the student does not like living in the room. Note that you can never assign a student to a room which he/she has not rated, as the absence of rating indicates that the student cannot live in the room for other reasons.
    With limited information available, you've decided to simply find an assignment such that every student is assigned to a room he/she has rated, no two students are assigned to the same room, and the sum of rating is maximized while satisfying Peterson's requirement. The question is … what exactly is the answer?
     
    题意描述:学校里有n个学生和m个公寓房间,每个学生对一些房间有一些打分,如果分数为正,说明学生喜欢这个房间,若为0,对这个房间保持中立,若为负,则不喜欢这个房间。学生不会住进不喜欢的房间和没有打分的房间。问安排这n个学生来求最大的分数。
    算法分析:KM算法。n个学生作为X集,m个房间作为Y集,然后调用KM算法就可以了。
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<algorithm>
      7 #define inf 0x7fffffff
      8 using namespace std;
      9 const int maxn=500+10;
     10 
     11 int n,m;
     12 int lx[maxn],ly[maxn],visx[maxn],visy[maxn];
     13 int link[maxn],slack[maxn],w[maxn][maxn];
     14 
     15 int dfs(int x)
     16 {
     17     visx[x]=1;
     18     for (int y=1 ;y<=m ;y++) if (w[x][y]!=-1)
     19     {
     20         if (visy[y]) continue;
     21         int t=lx[x]+ly[y]-w[x][y];
     22         if (t==0)
     23         {
     24             visy[y]=1;
     25             if (link[y]==-1 || dfs(link[y]))
     26             {
     27                 link[y]=x;
     28                 return 1;
     29             }
     30         }
     31         else if (slack[y]>t) slack[y]=t;
     32     }
     33     return 0;
     34 }
     35 
     36 int KM()
     37 {
     38     memset(link,-1,sizeof(link));
     39     memset(ly,0,sizeof(ly));
     40     for (int x=1 ;x<=n ;x++)
     41     {
     42         lx[x]=-inf;
     43         for (int y=1 ;y<=m ;y++)
     44             lx[x]=max(lx[x],w[x][y]);
     45     }
     46     for (int x=1 ;x<=n ;x++)
     47     {
     48         for (int i=1 ;i<=m ;i++) slack[i]=inf;
     49         int flag=0;
     50         for (int i=1 ;i<=m ;i++) if (w[x][i]!=-1) flag=1;
     51         while (flag)
     52         {
     53             memset(visx,0,sizeof(visx));
     54             memset(visy,0,sizeof(visy));
     55             if (dfs(x)) break;
     56             int d=inf;
     57             for (int i=1 ;i<=m ;i++)
     58                 if (!visy[i] && d>slack[i]) d=slack[i];
     59             for (int i=1 ;i<=n ;i++)
     60                 if (visx[i]) lx[i] -= d;
     61             for (int i=1 ;i<=m ;i++)
     62             {
     63                 if (visy[i]) ly[i] += d;
     64                 else slack[i] -= d;
     65             }
     66         }
     67     }
     68     int ans=0;
     69     int vis[maxn];
     70     memset(vis,0,sizeof(vis));
     71     for (int i=1 ;i<=m ;i++)
     72     {
     73         if (link[i]!=-1)
     74         {
     75             ans += w[link[i] ][i];
     76             vis[link[i] ]=1;
     77         }
     78     }
     79     int i=1;
     80     for (i=1 ;i<=n ;i++)
     81         if (vis[i]==0) return -1;
     82     return ans;
     83 }
     84 
     85 int main()
     86 {
     87     int e;
     88     int ncase=1;
     89     while (scanf("%d%d%d",&n,&m,&e)!=EOF)
     90     {
     91         memset(w,-1,sizeof(w));
     92         int a,b,c;
     93         for (int i=0 ;i<e ;i++)
     94         {
     95             scanf("%d%d%d",&a,&b,&c);
     96             a++ ;b++ ;
     97             if (c>=0) w[a][b]=c;
     98         }
     99         printf("Case %d: %d
    ",ncase++,KM());
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    Mykings僵尸网络更新基础设施,大量使用PowerShell脚本进行“无文件”攻击挖矿
    CrowdStrike《无文件攻击白皮书》——写得非常好
    CrowdStrike 在 MITRE ATT&CK 评估的所有 20 个步骤中实现了 100% 的检测覆盖率——利用 Carbanak 和 FIN7(CARBON SPIDER)的两个case做的评估,不一定全面
    如何检测Windows中的横向渗透攻击——还是EDR能力为主啊
    威胁检测及威胁狩猎的工具、资源大合集
    phpmyadmin 导出数据表
    SpringBoot项目的 log4j漏洞解决—JeecgBoot
    Springbootactuator的常用endpoint的使用说明
    SpringBoot重点详解使用Actuator进行健康监控
    git log 常用方法
  • 原文地址:https://www.cnblogs.com/huangxf/p/4339563.html
Copyright © 2011-2022 走看看