Poj 3565 Ants KM, poj3565antskm
Question:
Give the coordinates of n ant and n class apple trees. If each ant wants to take an apple tree, the route cannot be crossed and a feasible solution is proposed.
Analysis:
When the distance and the smallest value of a matching feasible ant are obtained, the KM algorithm can be directly used to find the matching of the minimum weight of a bipartite graph. Another approach is to assume a match first, and adjust it if there is a cross.
Code:
//poj 3565//sep9#include <iostream>#include <cmath>using namespace std;const int maxN=128;const double INF=999999999.0;double w[maxN][maxN],lx[maxN],ly[maxN],slack[maxN];int linky[maxN];int visx[maxN],visy[maxN];int nx,ny;double antX[maxN],antY[maxN],appleX[maxN],appleY[maxN];int ans[maxN];bool find(int x){visx[x]=true;for(int y=0;y<ny;++y){if(visy[y])continue;double t=lx[x]+ly[y]-w[x][y];if(fabs(t)<1e-6){visy[y]=true;if(linky[y]==-1||find(linky[y])){linky[y]=x;return true;}}else if(slack[y]>t)slack[y]=t;}return false;}int KM(){int i,j;memset(linky,-1,sizeof(linky));for(i=0;i<nx;++i) ly[i]=0;for(i=0;i<nx;++i)for(j=0,lx[i]=-INF;j<ny;++j)if(w[i][j]>lx[i])lx[i]=w[i][j];for(int x=0;x<nx;++x){for(i=0;i<ny;++i)slack[i]=INF;while(1){memset(visx,0,sizeof(visx));memset(visy,0,sizeof(visy));if(find(x))break;double d=INF;for(i=0;i<ny;++i)if(!visy[i]&&slack[i]<d)d=slack[i]; if(d==INF)return -1;for(i=0;i<nx;++i)if(visx[i])lx[i]-=d;for(i=0;i<ny;++i)if(visy[i])ly[i]+=d;elseslack[i]-=d;}}return 0;}double dis(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}int main(){int n,i,j;scanf("%d",&n);for(i=0;i<n;++i)scanf("%lf%lf",&antX[i],&antY[i]);for(i=0;i<n;++i)scanf("%lf%lf",&appleX[i],&appleY[i]);for(i=0;i<n;++i)for(j=0;j<n;++j)w[i][j]=-dis(antX[i],antY[i],appleX[j],appleY[j]);nx=ny=n;KM();for(i=0;i<n;++i)ans[linky[i]]=i;for(i=0;i<n;++i)printf("%d\n",ans[i]+1);return 0;}