poj3565 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
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值