题目描述:
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
Prev
Submit Status Statistics Discuss
Next
Type:
None
None Graph Theory 2-SAT Articulation/Bridge/Biconnected Component Cycles/Topological Sorting/Strongly Connected Component Shortest Path Bellman Ford Dijkstra/Floyd Warshall Euler Trail/Circuit Heavy-Light Decomposition Minimum Spanning Tree Stable Marriage Problem Trees Directed Minimum Spanning Tree Flow/Matching Graph Matching Bipartite Matching Hopcroft–Karp Bipartite Matching Weighted Bipartite Matching/Hungarian Algorithm Flow Max Flow/Min Cut Min Cost Max Flow DFS-like Backtracking with Pruning/Branch and Bound Basic Recursion IDA* Search Parsing/Grammar Breadth First Search/Depth First Search Advanced Search Techniques Binary Search/Bisection Ternary Search Geometry Basic Geometry Computational Geometry Convex Hull Pick’s Theorem Game Theory Green Hackenbush/Colon Principle/Fusion Principle Nim Sprague-Grundy Number Matrix Gaussian Elimination Matrix Exponentiation Data Structures Basic Data Structures Binary Indexed Tree Binary Search Tree Hashing Orthogonal Range Search Range Minimum Query/Lowest Common Ancestor Segment Tree/Interval Tree Trie Tree Sorting Disjoint Set String Aho Corasick Knuth-Morris-Pratt Suffix Array/Suffix Tree Math Basic Math Big Integer Arithmetic Number Theory Chinese Remainder Theorem Extended Euclid Inclusion/Exclusion Modular Arithmetic Combinatorics Group Theory/Burnside’s lemma Counting Probability/Expected Value Others Tricky Hardest Unusual Brute Force Implementation Constructive Algorithms Two Pointer Bitmask Beginner Discrete Logarithm/Shank’s Baby-step Giant-step Algorithm Greedy Divide and Conquer Dynamic Programming Tag it!
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 ≤ x, y ≤ 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
题解:
没想到现场搞出了一个神奇的方法:
随便连,然后暴力枚举边去调整.知道最后没有相交的
另外,可以用一个结论:权值最小的匹配一定是不相交的匹配,如果相交,总是可以调整使得更小.
重点:
(1)先随便连一种结果,再调整.
(2)画出不合法情况,只用两个来观察合法情况的特性
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <ctype.h>
#include <limits.h>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
#define CLR(a) memset(a, 0, sizeof(a))
#define REP(i, a, b) for(int i = a;i < b;i++)
#define REP_D(i, a, b) for(int i = a;i <= b;i++)
typedef long long ll;
using namespace std;
const double eps = 1e-10;
const double PI = acos(-1.0);
const int maxn = 100+10;
int dcmp(double x)
{
if(fabs(x)<eps)
return 0;
if(x > 0)
return 1;
return -1;
}
struct Point
{
double x, y;
Point(double _x = 0, double _y = 0)
{
x = _x;
y = _y;
}
Point operator -(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
//叉积
double operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
int operator ==(const Point &b)const
{
if(dcmp(x-b.x)==0&&dcmp(y-b.y)==0)
return 1;
return 0;
}
//点积
double operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
double mo()
{
double ans = 0;
ans = sqrt(x*x+y*y);
return ans;
}
//变成长度是r的向量
void change(double r)
{
double k = r/mo();
x *= k;
y *= k;
}
};
double dist(Point a, Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
struct Line
{
Point s,e;
Line() {}
Line(Point _s,Point _e)
{
s = _s;
e = _e;
}
};
/*
*p点在L上面返回1
*p点不在L上面返回0
*/
bool OnSeg(Point P,Line L)
{
return
dcmp((L.s-P)^(L.e-P)) == 0 &&
dcmp((P.x - L.s.x) * (P.x - L.e.x)) <= 0 &&
dcmp((P.y - L.s.y) * (P.y - L.e.y)) <= 0;
}
/*
线段相交
*相交返回1
*不相交返回0
*/
bool inter(Line l1,Line l2)
{
return
max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
dcmp((l2.s-l1.e)^(l1.s-l1.e))*dcmp((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&
dcmp((l1.s-l2.e)^(l2.s-l2.e))*dcmp((l1.e-l2.e)^(l2.s-l2.e)) <= 0;
}
Point a[maxn], b[maxn];
int conct[maxn], n;
void solve()
{
for(int i = 1;i<=n;i++)
{
conct[i] = i;
}
while(1)
{
int flag = 1;
for(int i = 1;i<=n;i++)
{
for(int j = i+1;j<=n;j++)
{
Line tmpa(a[i], b[conct[i]]);
Line tmpb(a[j], b[conct[j]]);
if(inter(tmpa, tmpb))
{
flag = 0;
swap(conct[i], conct[j]);
}
}
}
if(flag==1)
{
for(int i = 1;i<=n;i++)
{
printf("%d\n", conct[i]);
}
break;
}
}
}
int main()
{
// freopen("1Ain.txt", "r", stdin);
//freopen("1Aout.txt", "w", stdout);
while(scanf("%d", &n)!=EOF)
{
for(int i = 1;i<=n;i++)
scanf("%lf%lf", &a[i].x, &a[i].y);
for(int i = 1;i<=n;i++)
scanf("%lf%lf", &b[i].x, &b[i].y);
solve();
}
return 0;
}