zoukankan      html  css  js  c++  java
  • poj 2400(最小权匹配)

    题意:给出雇主对雇员的满意度和雇员对雇主的满意度,分数越低代表评价越高,求给出最优匹配方案。当有多种最优匹配,全部输出!

    思路:典型的最小权匹配,km算法求解

    View Code
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 #define inf 0x3f3f3f3f
      7 #define N 111
      8 int net[N][N],x[N],y[N],lx[N],ly[N],link[N],b[N],like[N];
      9 int n,sum,d,cnt;
     10 bool km_dfs(int u)
     11 {
     12     x[u]=1;
     13     for(int i=1;i<=n;i++)
     14     {
     15         if(y[i])continue;
     16         int t=lx[u]+ly[i]-net[u][i];
     17         if(t==0)
     18         {
     19             y[i]=1;
     20             if(!link[i]||km_dfs(link[i]))
     21             {
     22                 link[i]=u;
     23                 return true;
     24             }
     25         }
     26         else d=min(d,t);
     27     }
     28     return false;
     29 }
     30 double km()
     31 {
     32     memset(lx,0,sizeof(lx));
     33     memset(ly,0,sizeof(ly));
     34     memset(link,0,sizeof(link));
     35     for(int i=1;i<=n;i++)
     36     {
     37         while(1){
     38             d=inf;
     39             memset(x,0,sizeof(x));
     40             memset(y,0,sizeof(y));
     41             if(km_dfs(i))break;
     42             for(int j=1;j<=n;j++)
     43             {
     44                 if(x[j])lx[j]-=d;
     45                 if(y[j])ly[j]+=d;
     46             }
     47         }
     48     }
     49     sum=0;
     50     for(int i=1;i<=n;i++)
     51     {
     52         sum-=lx[i]+ly[i];
     53     }
     54     return 1.0*sum/(n*2);
     55 }
     56 void dfs(int step,int total)
     57 {
     58     if(total>sum)return ;
     59     if(step==n+1)
     60     {
     61         printf("Best Pairing %d\n",cnt++);
     62         for(int i=1;i<=n;i++)
     63         printf("Supervisor %d with Employee %d\n",i,like[i]);
     64         return ;
     65     }
     66     for(int i=1;i<=n;i++)
     67     {
     68         if(!b[i]){
     69             b[i]=1;
     70             like[step]=i;
     71             dfs(step+1,total-net[step][i]);
     72             b[i]=0;
     73         }
     74     }
     75 }
     76 int main()
     77 {
     78     int ca;
     79     scanf("%d",&ca);
     80     int cas=1;
     81     while(ca--)
     82     {
     83         int x;
     84         cnt=1;
     85         memset(net,0,sizeof(net));
     86         scanf("%d",&n);
     87         for(int i=1;i<=n;i++)
     88         {
     89             for(int j=1;j<=n;j++)
     90             {
     91                 scanf("%d",&x);
     92                 net[x][i]-=j;
     93             }
     94         }
     95         for(int i=1;i<=n;i++)
     96         {
     97             for(int j=1;j<=n;j++)
     98             {
     99                 scanf("%d",&x);
    100                 net[i][x]-=j;//最小权匹配取负数
    101             }
    102         }
    103         double ans=km();
    104         printf("Data Set %d, Best average difference: %.6lf\n",cas++,ans-1);
    105         memset(b,0,sizeof(b));
    106         dfs(1,0);
    107         printf("\n");
    108     }
    109     return 0;
    110 }
  • 相关阅读:
    webapi之fiddler头设置
    ios---setContentOffset
    webapi参数处理get过个参数
    socket网络编程
    logging模块
    configparser模块(拷贝)
    hashlib模块--摘要算法
    异常处理
    面向对象拓展
    反射
  • 原文地址:https://www.cnblogs.com/huangriq/p/2497667.html
Copyright © 2011-2022 走看看