码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ3862:Intersection

时间:2015-04-13 21:00:59      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:zoj

Edward has 2n points on the plane conveniently labeled with 1,2,…,2n. Each point is connected exactly with another point by a segment.

Edward finds that some segments intersecting with some others. So he wants to eliminate those intersections with the following operation: choose two points i and j (1 ≤ ij ≤ 2n) and swap their coordinates.

技术分享

For example, Edward has 4 points (0, 0), (0, 1), (1, 1), (1, 0). Point 1 is connected with point 3 and point 2 is connected with 4. Edward can choose to swap the coordinates of point 2 and point 3.

Edward wants to know whether it is possible to use at most n + 10 operations to achieve his goal.

No two points coincide and no three points are on the same line.

Input

There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:

The first line contains an integer n (1 ≤ n ≤ 100000).

Each of the following 2n lines contains 2 integers xiyi which denotes the point (xiyi). (|xi|, |yi| ≤ 109).

Each of the following n lines contains 2 integers aibi (1 ≤ aibi ≤ 2nai ≠ bi), which means point ai and point bi are connected by a segment.

The sum of values n for all the test cases does not exceed 300000.

Output

For each test case, print a line containing an integer m, indicating the number of operations needed. You must assure that m is no larger than n + 10. If you cannot find such a solution, just output "-1" and ignore the following output.

In the next m lines, each contains two integers i and j (1 ≤ ij ≤ 2n), indicating an operation, separated by one space.

If there are multiple solutions, any of them is accepted.

Sample Input

1
2
0 0
0 1
1 1
1 0
1 3
2 4

Sample Output

1
2 3

给定的n条线段中有一些可能是相交的,但我们通过对一些点经过一些交换,可以使得所有线段都不相交,要求输出方法
首先,题目并没有要求最少步数,只要求步数少于n+10即可,既然这样放宽了条件的话,就可以暴力解决了
我们先把所有点排序,按x越小y越大来排好顺序,那么我们可以从最左上的点开始,如果1点和2点不想连,假设1点与x点相连,通过交换2与x点,那么得到一条最边界的线段,而这条线段必然与其他线段都是不想交的,然后以此类推去交换其他所有的点

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;
#define ls 2*i
#define rs 2*i+1
#define up(i,x,y) for(i=x;i<=y;i++)
#define down(i,x,y) for(i=x;i>=y;i--)
#define mem(a,x) memset(a,x,sizeof(a))
#define w(a) while(a)
#define LL long long
const double pi = acos(-1.0);
#define Len 200005
#define mod 998244353
const LL inf = 1<<30;

int t,n;
struct node
{
    int x,y,id;
} a[Len];
int to[Len],ans[Len][2],len;
int now[Len],ori[Len];

int cmp(node a,node b)
{
    if(a.y == b.y)
        return a.x<b.x;
    return a.y>b.y;
}

int main()
{
    int i,j,k,x,y;
    scanf("%d",&t);
    w(t--)
    {
        scanf("%d",&n);
        up(i,1,2*n)
        {
            scanf("%d%d",&a[i].x,&a[i].y);
            a[i].id = i;
        }
        mem(to,0);
        up(i,1,n)
        {
            scanf("%d%d",&x,&y);
            to[x] = y;
            to[y] = x;
        }
        len = 0;
        sort(a+1,a+1+2*n,cmp);
        up(i,1,2*n)
        {
            now[i] = a[i].id;
            ori[a[i].id] = i;
        }
        len = 0;
        up(i,1,n)
        {
            int l = 2*i-1;
            int r = 2*i;
            if(to[now[l]]==now[r]) continue;
            else
            {
                ans[len][0] = now[r];
                ans[len][1] = to[now[l]];
                len++;
                ori[now[r]] = ori[to[now[l]]];
                now[ori[to[now[l]]]]=now[r];
                ori[to[now[l]]]=r;
            }
        }
        printf("%d\n",len);
        up(i,0,len-1)
            printf("%d %d\n",ans[i][0],ans[i][1]);
    }

    return 0;
}


ZOJ3862:Intersection

标签:zoj

原文地址:http://blog.csdn.net/libin56842/article/details/45030277

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!