poj3565Ants(KM-几何与图论的结合)

链接

可以看出蓝的之和一定比红的之和要大,也就是说符合条件的匹配一定是权值最小的,所以二分图的最佳完美匹配。。KM

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 110
 12 #define LL long long
 13 #define INF 9999999999.0
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 struct point
 18 {
 19     int x,y;
 20     //point(int x=0,int y=0):x(x),y(y){}
 21 }p[N<<1];
 22 double dis(point a,point b)
 23 {
 24     return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y));
 25 }
 26 double dcmp(double x)
 27 {
 28     if(fabs(x)<eps) return 0;
 29     return x<0?-1:1;
 30 }
 31 double w[N][N];
 32 int n,link[N],x[N],y[N];
 33 double lx[N],ly[N],slack[N],d;
 34 bool match(int u)
 35 {
 36     x[u] = 1;
 37     for(int i = 1; i <= n ; i++)
 38     {
 39         if(y[i]) continue;
 40         double o = lx[u]+ly[i]-w[u][i];
 41         if(dcmp(o)==0)
 42         {
 43             y[i] = 1;
 44             if(!link[i]||match(link[i]))
 45             {
 46                 link[i] = u;
 47                 return true;
 48             }
 49         }
 50         else if(slack[i]>o) slack[i] = o;
 51     }
 52     return false;
 53 }
 54 void km()
 55 {
 56     int i,j;
 57     for(i = 1 ;i <= n ;i++)
 58     lx[i] = -INF;
 59     memset(ly,0,sizeof(ly));
 60     memset(link,0,sizeof(link));
 61     for(i = 1; i <= n ;i++)
 62         for(j = 1; j <= n ;j++)
 63         lx[i] = max(lx[i],w[i][j]);
 64     for(i = 1; i <= n ;i++)
 65     {
 66         for(j = 1; j <= n;j++)
 67         slack[j] = INF;
 68         for(;;)
 69         {
 70              d = INF;
 71             memset(x,0,sizeof(x));
 72             memset(y,0,sizeof(y));
 73             if(match(i)) break;
 74             for(j =1 ; j <= n ;j++)
 75             if(!y[j]&&d>slack[j]) d =min(d,slack[j]);
 76             for(j =1 ;j <= n ;j++) if(x[j]){lx[j]-=d;}
 77             for(j =1 ;j <= n ;j++) if(y[j]){ly[j]+=d;}
 78            // else slack[j]-=d;
 79             //cout<<",";
 80         }
 81     }
 82 }
 83 
 84 int main()
 85 {
 86     int i,j;
 87     while(scanf("%d",&n)!=EOF)
 88     {
 89         //init();
 90         for(i = 1; i <=n+n; i++)
 91         scanf("%d%d",&p[i].x,&p[i].y);
 92         for(i  =1; i <= n ;i++)
 93             for(j = 1; j <= n ; j++)
 94             {
 95                 w[i][j] = -dis(p[i+n],p[j]);
 96             }
 97         km();
 98         for(i = 1; i <= n ;i++)
 99         printf("%d\n",link[i]);
100     }
101     return 0;
102 }
View Code

 

posted @ 2014-07-29 11:05  _雨  阅读(183)  评论(0编辑  收藏  举报