题解:
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\n",kkk-ans%100,(ans-ans1)/100); } }