问题应用背景就不废话了,直接上code吧: /* Name: 最佳匹配 Copyright: moon@whu Author: moon Date: 08-08-06 10:31 Description: 算法 Kuhn_Munkras ,dfs找增广路径 cx[x] means x match cx[x], cy[y] means cy[y] match y */ #include <iostream> using namespace std; const int MAXN = 300; const int INF = 98765432; int n,m, g[MAXN][MAXN],sx[MAXN],sy[MAXN],cx[MAXN],cy[MAXN]; int lx[MAXN], ly[MAXN]; int path(int u) { sx[u]=1; for(int v=1;v<=n;v++) if(g[u][v]==lx[u]+ly[v] && !sy[v]){ sy[v]=1; if(!cy[v] || path(cy[v])) { cx[u]=v; cy[v]=u; return 1;} } return 0; } int perfectMatch() { int i,j,k,d; memset(lx,0,sizeof(lx)); memset(ly,0,sizeof(ly)); memset(cx,0,sizeof(cx)); memset(cy,0,sizeof(cy)); for(i=1; i<=n; i++) for(j=1; j<=n; j++) if(g[i][j]>lx[i]) lx[i] = g[i][j]; for(k=1; k<=n; k++){ memset(sy,0,sizeof(sy)); memset(sx,0,sizeof(sx)); if( path(k) ) continue; //找增广路径 k--; d=INF; for(i=1; i<=n; i++) if(sx[i]) //求最小修改量 d for(j=1; j<=n; j++) if(!sy[j] &&lx[i]+ly[j]-g[i][j]<d) d = lx[i]+ly[j]-g[i][j]; for(i=1; i<=n; i++) {//修改lx,ly if(sx[i]) lx[i] -= d; if(sy[i]) ly[i] += d; } } k=0; for(i=1; i<=n; i++) k+=g[i][cx[i]]; return k; } int main() { int i,j,k; while(scanf("%d%d",&n,&m)!=EOF) { memset(g,0,sizeof(g)); while(m--){ scanf("%d%d%d",&i,&j,&k); //求权和最大匹配,若求最小可通过取 -k 实现 g[i][j] = k; } k = perfectMatch(); printf("%d/n",k); } return 0; } /* test case: 4 5 1 1 1 1 2 2 1 4 5 2 3 5 4 3 6 */ ---比较经典的算法..