HDU 2813

http://acm.hdu.edu.cn/showproblem.php?pid=2813

裸二分图最优匹配,需要用两个map把武将名字映射到点的序号上

#include <iostream>

#include <cstdio>

#include <cstring>

#include <map>

using namespace std;

const int N=210;

const int INF=0x3f3f3f3f;

int nx,ny;

int linker[N],lx[N],ly[N],slack[N];  

int visx[N],visy[N],w[N][N];

int DFS(int x)

{

    visx[x]=1;

    for(int y=1;y<=ny;y++){

        if(visy[y])

            continue;

        int tmp=lx[x]+ly[y]-w[x][y];

        if(tmp==0){

            visy[y]=1;

            if(linker[y]==-1 || DFS(linker[y])){

                linker[y]=x;

                return 1;

            }

        }else if(slack[y]>tmp){ 

            slack[y]=tmp;

        }

    }

    return 0;

}

int KM()

{

    int i,j;

    memset(linker,-1,sizeof(linker));

    memset(ly,0,sizeof(ly));

    for(i=1;i<=nx;i++)      

        for(j=1,lx[i]=-INF;j<=ny;j++)

            if(w[i][j]>lx[i])

                lx[i]=w[i][j];

    for(int x=1;x<=nx;x++){

        for(i=1;i<=ny;i++)

            slack[i]=INF;

        while(1){

            memset(visx,0,sizeof(visx));

            memset(visy,0,sizeof(visy));

            if(DFS(x))  

                break;  

            int d=INF;

            for(i=1;i<=ny;i++)

                if(!visy[i] && d>slack[i])

                    d=slack[i];

            for(i=1;i<=nx;i++)

                if(visx[i])

                    lx[i]-=d;

            for(i=1;i<=ny;i++) 

                if(visy[i])

                    ly[i]+=d;

                else

                    slack[i]-=d;

        }

    }

    int res=0;

    for(i=1;i<=ny;i++)

        if(linker[i]!=-1)

            res+=w[linker[i]][i];

    return res;

}

int main()

{

    int n,m,k ;

    while(~scanf("%d%d%d",&n,&m,&k))

    {

        nx=n;ny=m;

        for(int i=0 ;i<N ;i++)

            for(int j=0 ;j<N ;j++)

                w[i][j]=-INF ;

          int p1=1,p2=1 ;

          map <string,int> mp1,mp2 ;

        for(int i=0 ;i<k ;i++)

        {

            char a[205],b[205] ;

            int v ;

            scanf("%s%s%d",a,b,&v) ;

            string s1(a),s2(b) ;

            if(!mp1[s1])mp1[s1]=p1++ ;

            if(!mp2[s2])mp2[s2]=p2++ ;

            w[mp1[s1]][mp2[s2]]=-v ;

        }

        int ans=KM();

        printf("%d\n",-ans);

    }    

    return 0;

}
View Code

 

你可能感兴趣的:(HDU)