• 二分图最佳匹配,求最大权匹配或最小权匹配


    Beloved Sons http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1338

    题意:国王有N个儿子,现在每个儿子结婚都能够获得一定的喜悦值,王子编号为1-N,有N个女孩的编号同样为1-N,每个王子心中都有心仪的女孩,现在问如果安排,能够使得题中给定的式子和最大。

    分析:其实题目中那个开根号是个烟雾弹,只要关心喜悦值的平方即可。那么对王子和女孩之间构边,边权为喜悦值的平方,对于每一个王子虚拟出一个女孩边权为0,这样是为了所有的王子都能够有女孩可以配对,以便算法能够正确的执行。

    求二分图最佳匹配,要求权值最大,lmatch返回一个最佳匹配。

     1 #include<cstdio>
     2 #include<cstring>
     3 #define mt(a,b) memset(a,b,sizeof(a))
     4 const int inf=0x3f3f3f3f;
     5 class Kuhn_Munkras { ///二分图最佳匹配O(ln*ln*rn)邻接阵
     6     typedef int typec;///边权的类型
     7     static const int MV=1024;///点的个数
     8     int ln,rn,s[MV],t[MV],ll[MV],rr[MV],p,q,i,j,k;
     9     typec mat[MV][MV];
    10 public:
    11     int lmatch[MV],rmatch[MV];
    12     void init(int tln,int trn) { ///传入ln左部点数,rn右部点数,要求ln<=rn,下标0开始
    13         ln=tln;
    14         rn=trn;
    15         for(i=0; i<ln; i++)
    16             for(j=0; j<rn; j++)
    17                 mat[i][j]=-inf;
    18     }
    19     void add(int u,int v,typec w) {///最小权匹配可将权值取相反数
    20         mat[u][v]=w;
    21     }
    22     typec solve() {///返回最佳匹配值,-1表示无法匹配
    23         typec ret=0;
    24         for (i=0; i<ln; i++) {
    25             for (ll[i]=-inf,j=0; j<rn; j++)
    26                 ll[i]=mat[i][j]>ll[i]?mat[i][j]:ll[i];
    27             if( ll[i] == -inf ) return -1;// 无法匹配!
    28         }
    29         for (i=0; i<rn; rr[i++]=0);
    30         mt(lmatch,-1);
    31         mt(rmatch,-1);
    32         for (i=0; i<ln; i++) {
    33             mt(t,-1);
    34             for (s[p=q=0]=i; p<=q&&lmatch[i]<0; p++)
    35                 for (k=s[p],j=0; j<rn&&lmatch[i]<0; j++)
    36                     if (ll[k]+rr[j]==mat[k][j]&&t[j]<0) {
    37                         s[++q]=rmatch[j],t[j]=k;
    38                         if (s[q]<0)
    39                             for (p=j; p>=0; j=p)
    40                                 rmatch[j]=k=t[j],p=lmatch[k],lmatch[k]=j;
    41                     }
    42             if (lmatch[i]<0) {
    43                 for (i--,p=inf,k=0; k<=q; k++)
    44                     for (j=0; j<rn; j++)
    45                         if(t[j]<0&&ll[s[k]]+rr[j]-mat[s[k]][j]<p)
    46                             p=ll[s[k]]+rr[j]-mat[s[k]][j];
    47                 for (j=0; j<rn; rr[j]+=t[j]<0?0:p,j++);
    48                 for (k=0; k<=q; ll[s[k++]]-=p);
    49             }
    50         }
    51         for (i=0; i<ln; i++) {
    52             if( lmatch[i] < 0 ) return -1;
    53             if( mat[i][lmatch[i]] <= -inf ) return -1;
    54             ret+=mat[i][lmatch[i]];
    55         }
    56         return ret;
    57     }
    58 } gx;
    59 int a[512];
    60 int main() {
    61     int t,n,m;
    62     while(~scanf("%d",&t)) {
    63         while(t--) {
    64             scanf("%d",&n);
    65             for(int i=0; i<n; i++) {
    66                 scanf("%d",&a[i]);
    67                 a[i]*=a[i];
    68             }
    69             gx.init(n,n<<1);
    70             for(int i=0,j; i<n; i++) {
    71                 scanf("%d",&m);
    72                 while(m--) {
    73                     scanf("%d",&j);
    74                     gx.add(i,j-1,a[i]);
    75                 }
    76                 gx.add(i,i+n,0);
    77             }
    78             int flag=gx.solve();
    79             for(int i=0; i<n; i++) {
    80                 int ans=0;
    81                 if(gx.lmatch[i]<n) {
    82                     ans=gx.lmatch[i]+1;
    83                 }
    84                 printf("%d ",ans);
    85             }
    86             puts("");
    87         }
    88     }
    89     return 0;
    90 }
    View Code

    end

  • 相关阅读:
    svn版本控制器在vs2013中的使用
    在本地环境用虚拟机win2008 sever搭建VS2013 + SVN 代码版本控制环境
    luogu 2422 良好的感觉
    loj 10181 绿色通道
    luogu 2569 [SCOI2010]股票交易
    luogu 3946 ことりのおやつ(小鸟的点心)
    luogu 2865 [USACO06NOV]路障Roadblocks
    luogu 4554 小明的游戏
    luogu 2411 白银莲花池 && luogu 1606 Lilypad Pond
    luogu 2850 [USACO06DEC]虫洞Wormholes
  • 原文地址:https://www.cnblogs.com/gaolzzxin/p/4007226.html
Copyright © 2020-2023  润新知