首页 > 代码库 > HDU 2813

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