//简单KM,,要注意的是XOR是异或的意思。。不要看不懂。。我看了半天才知道。。
//这个知道了就可以很简单的KM了。。这个题目也可以用最小费用最大流来做。。但是图比较难建。。
#include <iostream>
#include <stdio.h>
#define MAX 105
#define min(a,b) a<b?a:b 
#define max(a,b) a>b?a:b
int lx[MAX],ly[MAX],match[MAX],visx[MAX],visy[MAX],lack,g;
int map[MAX][MAX];
using namespace std;
 
int dfs(int x)
{//匈牙利 
    visx[x]=1; 
    for(int i=0;i<g;i++){ 
        if(!visy[i] && lx[x]+ly[i]==map[x][i])
        { 
            visy[i]=1; 
            if(match[i]==-1 || dfs(match[i]))
            { 
                match[i]=x; 
                return 1; 
            } 
        } 
    } 
    return 0; 
}

int KM()

    int i,j,k; 
    for(i=0;i<g;i++)
    {//初始化顶标 
        lx[i]=INT_MIN; ly[i]=0; 
        for(j=0;j<g;j++) 
            lx[i]=max(map[i][j],lx[i]); 
    } 
    memset(match,-1,sizeof(match)); 
    for(i=0;i<g;i++)
    { 
        while(1){//直到每个点都成功匹配,才结束循环 
            memset(visx,0,sizeof(visx)); 
            memset(visy,0,sizeof(visy)); 
            if(dfs(i))break; //如果点 i 成功匹配,则不需要调整定标值 
 
            /*------------顶标调整------------*/ 
            int lack=INT_MAX;//顶标调整值 
            for(j=0;j<g;j++)
            { 
                if(visx[j])
                { 
                    for(k=0;k<g;k++)
                    {//取幅度最小的值为调整值 
                        if(!visy[k])lack=min(lx[j]+ly[k]-map[j][k],lack); 
                    } 
                } 
            } 
            for(j=0;j<g;j++){//调整已经得到匹配的点对的顶标值 
                if(visx[j])lx[j]-=lack; 
                if(visy[j])ly[j]+=lack; 
            } 
            /*---------------------------------*/ 
        } 
    } 
    int sum=0; 
    for(i=0;i<g;i++)
    { 
        if(match[i]!=-1)
            sum+=map[match[i]][i]; 
    } 
    return sum; 

int main()
{
    int n,i,j;
    char ch;
    int value[MAX];
    while(cin>>n)
    {
  memset(map,0,sizeof(map));
        if(n==0)break;
        for(i=0;i<n;i++)
            cin>>value[i];
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
            {
                cin>>ch;
                if(ch=='1')
                {

     //cout<<value[i]<<" "<<value[j]<<endl;
                    map[i][j]=value[i]^value[j];
    // cout<<map[i][j]<<endl;
     //cout<<" **********"<<endl;
                }
            }
 /* for(i=0;i<n;i++)
   {
    //cout<<endl;
            for(j=0;j<n;j++)
    cout<<map[i][j]<<" ";
   }*/
            g=n;
            int res=KM();
            cout<<res<<endl;

    }
    return 0;
}

posted on 2012-02-06 13:41  →木头←  阅读(312)  评论(0编辑  收藏  举报