POJ 3565 Ants

Ants

Time Limit: 5000ms

Memory Limit: 65536KB

This problem will be judged on PKU. Original ID: 3565
64-bit integer IO format: %lld      Java class name: Main

Young naturalist Bill studies ants in school. His ants feed on plant-louses that live on apple trees. Each ant colony needs its own apple tree to feed itself.

Bill has a map with coordinates of n ant colonies and n apple trees. He knows that ants travel from their colony to their feeding places and back using chemically tagged routes. The routes cannot intersect each other or ants will get confused and get to the wrong colony or tree, thus spurring a war between colonies.

Bill would like to connect each ant colony to a single apple tree so that all n routes are non-intersecting straight lines. In this problem such connection is always possible. Your task is to write a program that finds such connection.

On this picture ant colonies are denoted by empty circles and apple trees are denoted by filled circles. One possible connection is denoted by lines.

Input

The first line of the input file contains a single integer number n (1 ≤ n ≤ 100) — the number of ant colonies and apple trees. It is followed by n lines describing n ant colonies, followed by n lines describing n apple trees. Each ant colony and apple tree is described by a pair of integer coordinates x and y (−10 000 ≤ xy ≤ 10 000) on a Cartesian plane. All ant colonies and apple trees occupy distinct points on a plane. No three points are on the same line.

Output

Write to the output file n lines with one integer number on each line. The number written on i-th line denotes the number (from 1 to n) of the apple tree that is connected to the i-th ant colony.

Sample Input

5
-42 58
44 86
7 28
99 34
-13 -59
-47 -44
86 74
68 -75
-68 60
99 -60

Sample Output

4
2
1
5
3

Source

Northeastern Europe 2007

解题:看似是计算几何,实则KM算法即可求解

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <climits>
 4 #include <cstring>
 5 #include <cmath>
 6 using namespace std;
 7 const int INF = 0x3f3f3f3f;
 8 const int maxn = 310;
 9 int Link[maxn],n;
10 double W[maxn][maxn],Lx[maxn],Ly[maxn],slack[maxn];
11 bool S[maxn],T[maxn];
12 bool match(int u) {
13     S[u] = true;
14     for(int v = 1; v <= n; ++v) {
15         if(T[v]) continue;
16         double d = Lx[u] + Ly[v] - W[u][v];
17         if(fabs(d) < 1e-6) {
18             T[v] = true;
19             if(Link[v] == -1 || match(Link[v])) {
20                 Link[v] = u;
21                 return true;
22             }
23         } else if(d < slack[v]) slack[v] = d;
24     }
25     return false;
26 }
27 void update(){
28     double d = INF;
29     for(int i = 1; i <= n; ++i)
30         if(!T[i] && slack[i] < d)
31             d = slack[i];
32     for(int i = 1; i <= n; ++i){
33         if(S[i]) Lx[i] -= d;
34         if(T[i]) Ly[i] += d;
35         else slack[i] -= d;
36     }
37 }
38 double KuhnMunkras() {
39     for(int i = 1; i <= n; ++i) {
40         Lx[i] = Ly[i] = 0;
41         Link[i] = -1;
42         for(int j = 1; j <= n; ++j)
43             Lx[i] = max(Lx[i],W[i][j]);
44     }
45     for(int i = 1; i <= n; ++i){
46         for(int j = 1; j <= n; ++j) slack[j] = INF;
47         while(true){
48             memset(S,false,sizeof S);
49             memset(T,false,sizeof T);
50             if(match(i)) break;
51             update();
52         }
53     }
54     double ret = 0;
55     for(int i = 1; i <= n; ++i)
56         if(Link[i] > -1) ret += W[Link[i]][i];
57     return ret;
58 }
59 struct Point{
60     int x,y;
61 }p[maxn];
62 double calc(int a,int b){
63     double tmp =  (p[a].x - p[b].x)*(p[a].x - p[b].x);
64     tmp += (p[a].y - p[b].y)*(p[a].y - p[b].y);
65     return -sqrt(tmp);
66 }
67 int main() {
68     while(~scanf("%d",&n)){
69         memset(W,0,sizeof W);
70         for(int i = 0; i < n; ++i)
71             scanf("%d%d",&p[i].x,&p[i].y);
72         for(int i = 0; i < n; ++i)
73             scanf("%d%d",&p[i+n].x,&p[i+n].y);
74         for(int i = 1; i <= n; ++i)
75             for(int j = 1; j <= n; ++j)
76                 W[i][j] = calc(i-1,j+n-1);
77         KuhnMunkras();
78         int ret[maxn];
79         for(int i = 1; i <= n; ++i)
80             ret[Link[i]] = i;
81         for(int i = 1; i <= n; ++i)
82             printf("%d\n",ret[i]);
83     }
84     return 0;
85 }

时间: 2024-10-28 14:50:29

POJ 3565 Ants的相关文章

poj 3565 Ants KM

题意: 给n只蚂蚁和n课苹果树的坐标,要让每只蚂蚁去一棵苹果树,路线不能重复,求一种可行方案. 分析: 当某种匹配可行时蚂蚁所走的距离和是最小的,可以直接用KM算法求二分图最小权值匹配.还有一种做法是先假定一种匹配,如果其中有交叉就进行调整. 代码: //poj 3565 //sep9 #include <iostream> #include <cmath> using namespace std; const int maxN=128; const double INF=9999

POJ 1852 Ants

Ants Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 15617   Accepted: 6753 Description An army of ants walk on a horizontal pole of length l cm, each with a constant speed of 1 cm/s. When a walking ant reaches an end of the pole, it imm

POJ 1852 Ants 思维题 简单题

Ants Description An army of ants walk on a horizontal pole of length l cm, each with a constant speed of 1 cm/s. When a walking ant reaches an end of the pole, it immediatelly falls off it. When two ants meet they turn back and start walking in oppos

POJ 1852 Ants 分析

1.暴搜 每只蚂蚁朝向有两种,可以枚举n只蚂蚁的朝向,然后模拟蚂蚁相遇的情景,总共2^n中情况. 2.分析ants相碰的情况: (a->)  (<-b) 变成 (<-a)(b->) 由于每只蚂蚁是相同的,所以等价与(<-b)(a->),这和两只蚂蚁原来的走向是一样的,即把碰撞当作没发生过 所以可以对每一只蚂蚁检查一次就可以了 3.空间优化 存蚂蚁的初始位置O(n),但是我们每次只要比较 a[i] 和 len-a[i] 就可以了,后面不需要这两个值了,所以完全可以用一个x

POJ 1852 Ants (思维技巧 + 贪心)

Ants Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10639   Accepted: 4718 Description An army of ants walk on a horizontal pole of length l cm, each with a constant speed of 1 cm/s. When a walking ant reaches an end of the pole, it imm

poj 1825 Ants 水题

Ants Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10722   Accepted: 4752 Description An army of ants walk on a horizontal pole of length l cm, each with a constant speed of 1 cm/s. When a walking ant reaches an end of the pole, it imm

poj 1852 Ants(贪心)

Ants Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 14061   Accepted: 6134 Description An army of ants walk on a horizontal pole of length l cm, each with a constant speed of 1 cm/s. When a walking ant reaches an end of the pole, it imm

水题/poj 1852 Ants

1 /* 2 PROBLEM:poj1852 3 AUTHER:Nicole 4 MEMO:水题 5 */ 6 #include<cstdio> 7 using namespace std; 8 int cmax(int a,int b){return a>b?a:b;} 9 int cmin(int a,int b){return a<b?a:b;} 10 int main() 11 { 12 int cases; 13 scanf("%d",&cas

poj -1852 ants (思维题)

n只蚂蚁以每秒1cm的速度在长为Lcm的杆子上爬行,当蚂蚁爬到杆子的端点时就会掉落,由于杆子太细,两只蚂蚁相遇时,他们不能交错通过,只能各自反向爬回去,对于每只蚂蚁,我们知道它距离杆子左端的距离为x,但不知道它当前的朝向,请计算所有蚂蚁落下杆子所需的最短时间很最长时间. #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring&g