模板题。用输入挂。
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> #define B(x) (1<<(x)) using namespace std; typedef long long ll; void cmax(int& a,int b){ if(b>a)a=b; } void cmin(int& a,int b){ if(b<a)a=b; } void cmax(ll& a,ll b){ if(b>a)a=b; } void cmin(ll& a,ll b){ if(b<a)a=b; } void add(int& a,int b,int mod){ a=(a+b)%mod; } void add(ll& a,ll b,ll mod){ a=(a+b)%mod; } const int oo=0x3f3f3f3f; const int MOD=1000000007; const int maxn=333; int g[maxn][maxn]; int visx[maxn],visy[maxn]; int x[maxn],y[maxn]; int mat[maxn],slack[maxn]; int n; int dfs(int u){ visx[u]=1; for(int i=1;i<=n;i++){ if(visy[i])continue; if(x[u]+y[i]==g[u][i]){ visy[i]=1; if(mat[i]==-1||dfs(mat[i])){ mat[i]=u; return 1; } }else cmin(slack[i],x[u]+y[i]-g[u][i]); } return 0; } void KM(){ memset(mat,-1,sizeof mat); memset(x,0,sizeof x); memset(y,0,sizeof y); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cmax(x[i],g[i][j]); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++) slack[j]=oo; while(1){ memset(visx,0,sizeof visx); memset(visy,0,sizeof visy); if(dfs(i)) break; else{ int Min=oo; for(int j=1;j<=n;j++) if(!visy[j]) if(Min>slack[j]) Min=slack[j]; for(int j=1;j<=n;j++){ if(visx[j]) x[j]-=Min; if(visy[j]) y[j]+=Min; else slack[j]-=Min; } } } } } void read(int &num) { char in; bool neg=false; while(((in=getchar()) > '9' || in<'0') && in!='-') ; if(in=='-') { neg=true; while((in=getchar()) >'9' || in<'0'); } num=in-'0'; while(in=getchar(),in>='0'&&in<='9') num*=10,num+=in-'0'; if(neg) num=0-num; } int main(){ //freopen("E:\\read.txt","r",stdin); while(scanf("%d",&n)!=EOF){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) read(g[i][j]); KM(); int ans=0; for(int i=1;i<=n;i++) ans+=g[mat[i]][i]; printf("%d\n",ans); } return 0; }