【UVA11383】 Golden Tiger Claw 【二分图KM算法(板子)】
题目
题目传送门:https://www.luogu.com.cn/problem/UVA11383
分析
最近刚刚学了二分图,然后来了一个这样的题,看完题意之后,稍微想一想就能想出来是一个二分图,然后就是裸的板子解决。没什么难的。
代码
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define ll long long using namespace std; const int maxn=1e3+10; const int Inf=0x3f3f3f3f; ll n,mi; ll x[maxn],y[maxn],w[maxn][maxn],mat[maxn]; bool S[maxn],T[maxn]; bool Match(ll u){ S[u]=true; for(ll i=1;i<=n;++i){ if(!T[i]){ ll tmp(x[u]+y[i]-w[u][i]); if(!tmp){ T[i]=true; if(!mat[i] || Match(mat[i])){ mat[i]=u; return true; } } else mi=min(mi,tmp); } }return false; } void Update(){ for(ll i=1;i<=n;++i) if(S[i]) x[i]-=mi; for(ll i=1;i<=n;++i) if(T[i]) y[i]+=mi; } void KM(){ for(ll i=1;i<=n;++i){ mat[i]=x[i]=y[i]=0; for(ll j=1;j<=n;++j) x[i]=max(x[i],w[i][j]); } for(ll i=1;i<=n;++i){ while(true){ for(ll i=1;i<=n;++i) S[i]=T[i]=false; mi=Inf; if(Match(i)) break; else Update(); } } } int main(){ while(scanf("%d",&n)!=EOF&&n){ for(ll i=1;i<=n;++i) for(ll j=1;j<=n;++j) scanf("%d",&w[i][j]); KM(); ll ans=0; for(ll i=1;i<=n;++i) ans+=x[i]; for(ll i=1;i<=n;++i) ans+=y[i]; printf("%d",x[1]); for(ll i=2;i<=n;++i) printf(" %d",x[i]);printf("\n"); printf("%d",y[1]); for(ll i=2;i<=n;++i) printf(" %d ",y[i]);printf("\n"); printf("%d\n",ans); }return 0; }
$Never\ Give\ Up$