http://acm.hdu.edu.cn/showproblem.php?pid=3395
KM 水!!!
代码:
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<vector> #include<set> #include<queue> #include<map> #include<string> #include <iomanip> using namespace std; const int INF=0x3f3f3f3f; const int N=205; int L[N]; int dist[N][N]; int f[N]; bool lv[N],rv[N]; int a[N],b[N]; bool dfs(int x,int n) { lv[x]=true; for(int i=1;i<=n;++i) { if(!rv[i]&&a[x]+b[i]==dist[x][i]) { rv[i]=true; if(f[i]==-1||dfs(f[i],n)) { f[i]=x; return true; } } } return false; } int Km(int n) { memset(f,-1,sizeof(f)); memset(b,0,sizeof(b)); for(int i=1;i<=n;++i) { a[i]=-1; for(int j=1;j<=n;++j) a[i]=max(a[i],dist[i][j]); } for(int l=1;l<=n;++l) { while(true) { memset(lv,false,sizeof(lv)); memset(rv,false,sizeof(rv)); if(dfs(l,n)) break; int d=INF; for(int i=1;i<=n;++i) { if(lv[i]) for(int j=1;j<=n;++j) { if(!rv[j]) d=min(d,a[i]+b[j]-dist[i][j]); } } for(int i=1;i<=n;++i) { if(lv[i]) a[i]-=d; if(rv[i]) b[i]+=d; } } } int ans=0; for(int i=1;i<=n;++i) { if(f[i]!=-1) ans+=dist[f[i]][i]; } return ans; } void init(int n) { memset(dist,0,sizeof(dist)); int k[N]; for(int i=1;i<=n;++i) cin>>k[i]; for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) { char c; cin>>c; if(c=='1') dist[i][j]=(k[i]^k[j]); } } int main() { //freopen("data.in","r",stdin); int n; while(scanf("%d",&n)!=EOF) { if(n==0) break; init(n); printf("%d\n",Km(n)); } return 0; }