HDOJ 2813 - One fihgt one KM求最小权最大匹配..

来源:互联网 发布:淘宝c 编辑:程序博客网 时间:2024/05/21 06:25

                    题意:

                            告诉吕布的将军和曹操的将军PK某些对能赢..并且要付出一些HP的损失..问要让吕布的将军每轮都获胜..消耗的最小血量是多少..

                    题解:

                            用最小费用最大流做无限TLE...只能用KM搞了...把值置为相反数..结果取反就求除了最小权最大匹配...


Program:

#include<iostream>    #include<algorithm>    #include<stdio.h>    #include<string.h>   #include<map> #include<math.h>    #include<queue>    #define MAXN 1205  #define MAXM 8000005    #define oo 1000000007    #define ll long long    using namespace std;      //--------------------n为两侧的个数..w[][]为关系矩阵初始为-inf-------------------   int n;    int linker[MAXN],lx[MAXN],ly[MAXN],slack[MAXN];    int visx[MAXN],visy[MAXN],w[MAXN][MAXN];    int v[MAXN],h[MAXN],p[MAXN],a[MAXN],b[MAXN];      int DFS(int x){        visx[x]=1;        for(int y=1;y<=n;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 取最小的                slack[y]=tmp;            }        }        return 0;    }      int KM(){        int i,j;        memset(linker,-1,sizeof(linker));        memset(ly,0,sizeof(ly));        for(i=1;i<=n;i++)      //lx初始化为与它关联边中最大的            for(j=1,lx[i]=-oo;j<=n;j++)                if(w[i][j]>lx[i])                    lx[i]=w[i][j];        for(int x=1;x<=n;x++){            for(i=1;i<=n;i++)                slack[i]=oo;            while(1){                memset(visx,0,sizeof(visx));                memset(visy,0,sizeof(visy));                if(DFS(x)) break;                int d=oo;                for(i=1;i<=n;i++)                    if(!visy[i] && d>slack[i])                        d=slack[i];                for(i=1;i<=n;i++)                    if(visx[i])                        lx[i]-=d;                for(i=1;i<=n;i++)                    if(visy[i])                        ly[i]+=d;                    else                        slack[i]-=d;            }        }        int res=0;        for(i=1;i<=n;i++){            if(linker[i]==-1 || w[linker[i]][i]==-oo) continue;        res+=w[linker[i]][i];        }        return res;    }     //--------------------------------------------------------  struct node{      int son[65],w;}A[100005];int num,m;int trie(char *ss,int tp){      int i,h=0,x,len=strlen(ss);      for (i=0;i<len;i++)      {              if (ss[i]>='A' && ss[i]<='Z') x=ss[i]-'A';                                      else  x=ss[i]-'a'+27;              if (!A[h].son[x]) A[h].son[x]=++num;                h=A[h].son[x];      }      if (A[h].w) return A[h].w;      if (tp==1) return A[h].w=++n;      return A[h].w=++m;      }char ss[25];int main()   {                 int i,j,N,M,k,x,y,d,Af,Ac;       while (~scanf("%d%d%d",&N,&M,&k))      {               n=m=num=0;                memset(A,0,sizeof(A)),N=max(N,M);               for (i=1;i<=N;i++)                  for (j=1;j<=N;j++)                     w[i][j]=-oo;               while (k--)               {                        scanf("%s",ss),x=trie(ss,1);                        scanf("%s",ss),y=trie(ss,2);                               scanf("%d",&d);                         w[x][y]=-d;               }                n=max(n,m);               printf("%d\n",-KM());      }      return 0;  }  


原创粉丝点击