1 #include<cstring> 2 #include<cstdio> 3 #include<algorithm> 4 #include<iostream> 5 using namespace std; 6 const int mm=505; 7 const int oo=1e9; 8 int g[mm][mm]; 9 int lx[mm],ly[mm],Left[mm],slack[mm]; 10 bool S[mm],T[mm]; 11 int n; 12 bool match(int u) 13 { int tmp;S[u]=1; 14 for(int v=0;v<n;++v) 15 { 16 tmp=lx[u]+ly[v]-g[u][v]; 17 if(!T[v])///未选 18 { 19 if(tmp==0) 20 { T[v]=1;///add to tree 21 if(Left[v]==-1||match(Left[v])) 22 { 23 Left[v]=u;return 1; 24 } 25 } 26 else slack[v]=min(slack[v],tmp); 27 } 28 } 29 return 0; 30 } 31 void update() 32 { int ret=oo; 33 for(int i=0;i<n;++i) 34 if(!T[i]) 35 ret=min(ret,slack[i]); 36 for(int i=0;i<n;++i) 37 { 38 if(S[i])lx[i]-=ret; 39 if(T[i])ly[i]+=ret; 40 } 41 } 42 void getans() 43 { 44 for(int i=0;i<n;++i) 45 { ly[i]=0;lx[i]=0; 46 for(int j=0;j<n;++j) 47 lx[i]=max(lx[i],g[i][j]); 48 } 49 memset(Left,-1,sizeof(Left)); 50 for(int i=0;i<n;++i) 51 { 52 for(int j=0;j<n;++j)slack[j]=oo; 53 while(1) 54 { 55 for(int j=0;j<n;++j) 56 S[j]=T[j]=0; 57 if(match(i))break; 58 else update(); 59 } 60 } 61 } 62 int main() 63 { 64 while(~scanf("%d",&n)) 65 { 66 for(int i=0;i<n;++i) 67 for(int j=0;j<n;++j) 68 scanf("%d",&g[i][j]); 69 getans(); 70 int ans=0; 71 for(int i=0;i<n;++i)ans+=lx[i]+ly[i]; 72 for(int i=0;i<n-1;++i) 73 printf("%d ",lx[i]); 74 printf("%d\n",lx[n-1]); 75 for(int i=0;i<n-1;++i) 76 printf("%d ",ly[i]); 77 printf("%d\n",ly[n-1]); 78 printf("%d\n",ans); 79 } 80 return 0; 81 }