题意:
告诉吕布的将军和曹操的将军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;
}