Topic link
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=14347 Topic
There are n n white dots, n n black Dots, to the plane in the N-N-side, to ensure that each side is connected to a white dot and a black dot, and any two edges do not intersect, to find a legitimate solution. train of Thought
We can think of all the white dots as x sides, and all the black dots as y-sides, each white dot and all the black dots, the weight of the Euclidean distance between these two points, and then the KM algorithm, or to create a super source and super meeting point, running cost flow, the final can be the smallest matching of the binary graph, this is the answer.
Why is this idea correct? We can draw a picture to see:
Consider as shown on the left of the case, two white dots and two black dots, two sides have a cross, if we replace the two sides with the intersection of the edge (as above the right), then the two sides of the weight of the sum is necessarily reduced, the correctness is obvious. Code
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <
algorithm> #include <cmath> #define MAXV #define MAXE 60000 #define INF 1e9 using namespace std;
int s,t;
struct Edge {int u,v,cap,next;
Double W;
}edges[maxe];
int head[maxv],ncount=0;
void Addedge (int u,int v,int c,double W) {edges[++ncount].u=u;
Edges[ncount].v=v;
Edges[ncount].cap=c;
Edges[ncount].w=w;
Edges[ncount].next=head[u];
Head[u]=ncount;
} void Add (int u,int v,int c,double W) {Addedge (u,v,c,w);
Addedge (V,U,0,-W);
int Pre[maxv],q[maxe];
Double DIST[MAXV];
BOOL INQUEUE[MAXV];
BOOL Spfa () {memset (inqueue,false,sizeof (InQueue));//!!!!!
memset (pre,-1,sizeof (pre));
for (int i=0;i<maxv;i++) Dist[i]=inf;
int h=0,t=1;
Q[h]=s;
dist[s]=0;
Inqueue[s]=true;
while (h<t) {int u=q[h++];
Inqueue[u]=false; for (int p=head[u];p!=-1;p=edges[p].next)
{int v=edges[p].v;
if (dist[u]+edges[p].w<dist[v]&&edges[p].cap) {DIST[V]=DIST[U]+EDGES[P].W;
Pre[v]=p;
if (!inqueue[v]) {inqueue[v]=true;
Q[t++]=v;
}}} return pre[t]!=-1;
Double MCMF () {double cost=0;
while (SPFA ()) {if (dist[t]>=inf) break;
int flow=inf;
for (int p=pre[t];p!=-1;p=pre[edges[p].u]) flow=min (FLOW,EDGES[P].CAP);
for (int p=pre[t];p!=-1;p=pre[edges[p].u]) {edges[p].cap-=flow;
Edges[p^1].cap+=flow;
} Cost+=flow*dist[t];
} return cost; } struct point {double x,y}
WHITE[MAXV],BLACK[MAXV];
Double Eucliddistance (point A,point b) {return sqrt ((a.x-b.x) * (a.x-b.x) + (A.Y-B.Y) * (A.Y-B.Y));}
int ANS[MAXV];
int main () {int n; while (scanf ("%d", &n)!=eof) {memset (head,-1,sizeof (head));
Ncount=1;
S=maxv-2,t=maxv-1;
for (int i=1;i<=n;i++) {Add (s,i,1,0);
Add (i+n,t,1,0);
for (int i=1;i<=n;i++) scanf ("%lf%lf", &white[i].x,&white[i].y);
for (int i=1;i<=n;i++) scanf ("%lf%lf", &black[i].x,&black[i].y); for (int i=1;i<=n;i++) to (int j=1;j<=n;j++) Add (i,j+n,1,eucliddistance (WHITE[I],BLACK[J) ));
//!!!!!!
MCMF (); for (int i=1;i<=n;i++) for (int j=head[i];j!=-1;j=edges[j].next) {if (!edges[j].c
Ap&&edges[j].v>n) {ans[i]=edges[j].v-n;
Break
} for (int i=1;i<=n;i++) printf ("%d\n", Ans[i]);
return 0;
}