这题给了n个白点和n个黑点坐标,计算出他们两两配对的总路程最少,
我们算出他们之间的距离,为d,然后 w[j][i]=-d; 就将求最小值转化为求最大值,然后采用km进行匹配计算
1 #include <algorithm> 2 #include <string.h> 3 #include <iostream> 4 #include <cstdio> 5 #include <cmath> 6 using namespace std; 7 /* KM算法 8 * 复杂度O(nx*nx*ny) 9 * 求最大权匹配 10 * 若求最小权匹配,可将权值取相反数,结果取相反数 11 * 点的编号从0开始 12 */ 13 const int N = 105; 14 const double INF = 1000000.0; 15 int nx,ny; //两边的点数 16 double W[N][N]; //二分图描述 17 int Left[N];//y中各点匹配状态 18 double Lx[N],Ly[N]; // x,y中的点标号 19 double slack[N]; 20 bool S[N],T[N]; 21 int fab(double a, double b){ 22 if(fabs(a-b)<0.00000000001) return 0; 23 else return a-b>0?1:-1; 24 } 25 bool DFS(int x) { 26 S[x] = true; 27 for(int y = 0; y < ny; y++){ 28 if(T[y]) continue; 29 double tmp = Lx[x] + Ly[y] - W[x][y]; 30 if(fab(tmp,0)==0){ 31 T[y] = true; 32 if(Left[y] == -1 || DFS(Left[y])){ 33 Left[y] = x; 34 return true; 35 } 36 } 37 else if(slack[y] > tmp) 38 slack[y] = tmp; 39 } 40 return false; 41 } 42 void KM(){ 43 memset(Left, -1, sizeof(Left)); 44 memset(Ly,0, sizeof(Ly)); 45 for(int i = 0;i < nx;i++){ 46 Lx[i] = -INF; 47 for(int j = 0;j < ny;j++) 48 if(W[i][j] > Lx[i]) 49 Lx[i] = W[i][j]; 50 } 51 for(int x = 0;x < nx;x++){ 52 for(int i = 0;i < ny;i++) 53 slack[i] = INF; 54 while(true){ 55 memset(S, false, sizeof(S)); 56 memset(T, false, sizeof(T)); 57 if(DFS(x)) break; 58 double d = INF; 59 for(int i = 0;i < ny;i++) 60 if(!T[i] && d > slack[i]) 61 d = slack[i]; 62 for(int i = 0;i < nx;i++) 63 if(S[i]) 64 Lx[i] -= d; 65 for(int i = 0;i < ny;i++){ 66 if(T[i])Ly[i] += d; 67 else slack[i] -= d; 68 } 69 } 70 } 71 } 72 //HDU 2255 73 double x1[N],x2[N],yy1[N],yy2[N]; 74 int main() 75 { 76 int n,cccc=0; 77 while(scanf("%d",&n) == 1){ 78 if(cccc++)printf(" "); 79 for(int i = 0;i < n;i++) 80 scanf("%lf%lf",&x1[i],&yy1[i]); 81 for(int i=0; i<n; i++) 82 scanf("%lf%lf",&x2[i],&yy2[i]); 83 for(int i=0; i<n; i++) 84 for(int j=0; j<n; j++) 85 W[j][i]=-sqrt((x1[i]-x2[j])*(x1[i]-x2[j])+ 86 (yy1[i]-yy2[j])*(yy1[i]-yy2[j]) 87 ); 88 nx = ny = n; 89 KM(); 90 for(int i=0; i<n ;i++) 91 printf("%d ",Left[i]+1); 92 } 93 return 0; 94 }