hdu2853

题解:

KM算法模板

然后我把另一边加了点

然后写了#define int long long

然后莫名挂。。。

然后去掉就过了

代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=505;
int n,m,a[N][N],slack[N],x,exr[N],exl[N],match[N],visl[N],visr[N];
int dfs(int x)
{
    visl[x]=1;
    for (int i=1;i<=n;i++)
     if (!visr[i])
      {
          int k=exl[x]+exr[i]-a[x][i];
          if (k==0)
           {
               visr[i]=1;
               if (!match[i]||dfs(match[i]))
                {
                    match[i]=x;
                    return 1;
                }
           }
          else slack[i]=min(slack[i],k); 
      }
    return 0;  
}
int main()
{
    while (~scanf("%d%d",&n,&m))
     {
         int ans1=0;
         memset(a,0,sizeof a);
         for (int i=1;i<=n;i++)
         for (int j=1;j<=m;j++)
          scanf("%d",&x),a[j][i]=x*100;
        for (int i=1;i<=n;i++)
         scanf("%d",&x),ans1+=a[x][i],a[x][i]++;
        int kkk=n;n=m;
        memset(exl,0,sizeof exl);
        for (int i=1;i<=n;i++)
         for (int j=1;j<=n;j++)
          exl[i]=max(a[i][j],exl[i]);
        memset(match,0,sizeof match);
        memset(exr,0,sizeof exr);
        for (int i=1;i<=n;i++)
         {
             for (int j=1;j<=n;j++)slack[j]=1e9;
            while (1)
             {
                 memset(visl,0,sizeof visl);
                 memset(visr,0,sizeof visr);
                 if (dfs(i))break;
                 int d=1e9; 
                 for (int j=1;j<=n;j++)
                  if (!visr[j])d=min(d,slack[j]);
                 for (int j=1;j<=n;j++)
                 {
                     if (visl[j])exl[j]-=d;
                     if (visr[j])exr[j]+=d;
                     else slack[j]-=d;
                 } 
             }    
         }
        int ans=0;
        for (int i=1;i<=m;i++)
         ans+=a[match[i]][i];
        printf("%d %d
",kkk-ans%100,(ans-ans1)/100);  
     }
}
原文地址:https://www.cnblogs.com/xuanyiming/p/8284074.html