time limit per test2 seconds

memory limit per test256 megabytes

inputstandard input

outputstandard output

Student Vladislav came to his programming exam completely unprepared as usual. He got a question about some strange algorithm on a graph — something that will definitely never be useful in real life. He asked a girl sitting next to him to lend him some cheat papers for this questions and found there the following definition:

The minimum spanning tree T of graph G is such a tree that it contains all the vertices of the original graph G, and the sum of the weights of its edges is the minimum possible among all such trees.

Vladislav drew a graph with n vertices and m edges containing no loops and multiple edges. He found one of its minimum spanning trees and then wrote for each edge its weight and whether it is included in the found tree or not. Unfortunately, the piece of paper where the graph was painted is gone and the teacher is getting very angry and demands to see the original graph. Help Vladislav come up with a graph so that the information about the minimum spanning tree remains correct.

Input

The first line of the input contains two integers n and m () — the number of vertices and the number of edges in the graph.

Each of the next m lines describes an edge of the graph and consists of two integers aj and bj (1 ≤ aj ≤ 109, bj = {0, 1}). The first of these numbers is the weight of the edge and the second number is equal to 1 if this edge was included in the minimum spanning tree found by Vladislav, or 0 if it was not.

It is guaranteed that exactly n - 1 number {bj} are equal to one and exactly m - n + 1 of them are equal to zero.

Output

If Vladislav has made a mistake and such graph doesn’t exist, print  - 1.

Otherwise print m lines. On the j-th line print a pair of vertices (uj, vj) (1 ≤ uj, vj ≤ n, uj ≠ vj), that should be connected by the j-th edge. The edges are numbered in the same order as in the input. The graph, determined by these edges, must be connected, contain no loops or multiple edges and its edges with bj = 1 must define the minimum spanning tree. In case there are multiple possible solutions, print any of them.

Examples

input

4 5

2 1

3 1

4 0

1 1

5 0

output

2 4

1 4

3 4

3 1

3 2

input

3 3

1 0

2 1

3 1

output

-1

【题目链接】:http://codeforces.com/problemset/problem/606/D

【题解】



首先把那些在最小生成树中的边选出来;

并且从小到大排序;

然后从1一直到n;给每相邻的两个点之间按顺序分配这些n-条边即i-1到i的边权小于等于i到i+1的边权;

得到类似下面的生成树



然后处理第n到第m条边(不在最小生成树中的自由边);

同样按照从小到大的顺序排序;

以插入两条自由边

8和12为例;

先插入8;



为什么不插入在2上?因为不能有重边;

显然1..2这个节点已经是最小生成树了;接下来的问题就是要把3这个点和1和2这个生成树组合子啊一起;那问题就是要从1到3连一条边还是2到3连一条边;因为8>7显然这条边权为8的边不能加入到最后的最小生成树;所以可以添加这一条边而不影响最后的答案;

然后再插入12



这个过场相当于1-3号节点已经确定最小生成树的方案了;然后要加入一个节点4;那问题就变成要选3->4这条边还是选1->4这条边了;显然因为新插入的12>11所以在最终的最小生成树里面不会选12这条边;所以这样的加入方法是可行的;

再补充插入一个13



还是同一个问题;

即1..3已经确定最小生成树的方式了;

要把那个4加入到最小生成树中;

则选择2->4还是3->4?

显然因为11<13所以会选择3->4这条边;而不会选择新插入的13那条边;

同时,我们不必要和1->4刚才那个插入的比较;因为那条边是比3->4大的;且在做MST的时候不会选那条边;所以不用比;

因为不能重边;

所以新加入的边的起点和终点的差都为1(对应到边上,边的差为2);

然后我们按照优先终点不动先动起点的原则来构造这张图;

这样停留在终点越久;我们要加入的边大于终点-1到终点那条边的边权的机会更大;

因为是按照顺序搞的;所以如果遇到不满足大于等于前一条边的情况就要输出无解.



【完整代码】

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long using namespace std; const int MAXN = 1e5+100;
const int dx[5] = {0,1,-1,0,0};
const int dy[5] = {0,0,0,-1,1};
const double pi = acos(-1.0);
struct abc
{
int w,id,in;
}; int n,m;
abc a[MAXN];
int ans[MAXN][2]; void rel(LL &r)
{
r = 0;
char t = getchar();
while (!isdigit(t) && t!='-') t = getchar();
LL sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
} void rei(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)&&t!='-') t = getchar();
int sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
} bool cmp(abc a,abc b)
{
if (a.in == b.in)
return a.w < b.w;
else
return a.in > b.in;
} int main()
{
//freopen("F:\\rush.txt","r",stdin);
rei(n);rei(m);
for (int i = 1;i <= m;i++)
{
int x,y;
rei(x);rei(y);
a[i].id = i;a[i].w = x;a[i].in = y;
}
sort(a+1,a+1+m,cmp);
for (int i = 1;i <= n-1;i++)
ans[a[i].id][0] = i,ans[a[i].id][1] = i+1;
int to = 2,from = 0;
for (int i = n;i <= m;i++)
{
if (to == from+2)
{
from =1;
to++;
}
else
from++;
if (a[i].w < a[to-1].w)
{
puts("-1");
return 0;
}
ans[a[i].id][0] = from,ans[a[i].id][1] = to;
}
for (int i = 1;i <= m;i++)
printf("%d %d\n",ans[i][0],ans[i][1]);
return 0;
}

【22.73%】【codeforces 606D】Lazy Student的更多相关文章

  1. 【 BowWow and the Timetable CodeForces - 1204A 】【思维】

    题目链接 可以发现 十进制4 对应 二进制100 十进制16 对应 二进制10000 十进制64 对应 二进制1000000 可以发现每多两个零,4的次幂就增加1. 用string读入题目给定的二进制 ...

  2. 【32.22%】【codeforces 602B】Approximating a Constant Range

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  3. 【63.73%】【codeforces 560A】Currency System in Geraldion

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. 【22.70%】【codeforces 591C】 Median Smoothing

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  5. 【codeforces 766E】Mahmoud and a xor trip

    [题目链接]:http://codeforces.com/contest/766/problem/E [题意] 定义树上任意两点之间的距离为这条简单路径上经过的点; 那些点上的权值的所有异或; 求任意 ...

  6. 【codeforces 733F】Drivers Dissatisfaction

    [题目链接]:http://codeforces.com/problemset/problem/733/F [题意] 给你n个点m条边; 让你从中选出n-1条边; 形成一个生成树; (即让n个点都联通 ...

  7. 【codeforces 799D】Field expansion

    [题目链接]:http://codeforces.com/contest/799/problem/D [题意] 给你长方形的两条边h,w; 你每次可以从n个数字中选出一个数字x; 然后把h或w乘上x; ...

  8. 【codeforces 22C】 System Administrator

    [题目链接]:http://codeforces.com/problemset/problem/22/C [题意] 给你n个点; 要求你构造一个含m条边的无向图; 使得任意两点之间都联通; 同时,要求 ...

  9. 【77.78%】【codeforces 625C】K-special Tables

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

随机推荐

  1. MyBatis学习总结(14)——Mybatis使用技巧总结

    1. 区分 #{} 和 ${}的不同应用场景 1)#{} 会生成预编译SQL,会正确的处理数据的类型,而${}仅仅是文本替换. 对于SQL: select * from student where x ...

  2. COGS——C 908. 校园网 || 洛谷——P 2746 [USACO5.3]校园网Network of Schools

    http://www.cogs.pro/cogs/problem/problem.php?pid=908   ||  https://www.luogu.org/problem/show?pid=27 ...

  3. 素数表(Eratosthenes)

    怎么判断一个数是素数? 常规的方法是枚举从2开始的数,看看是否能被整除. 但是,如果要判断的数很多的时候,那么效率会十分低下.... 一个优化的方法是不用判断比这个数小的所有数(到平方根位置),而是判 ...

  4. 鲁德http://www.testroad.org/topic/76

     [最新的招聘信息]:1.联动优势科技有限公司招聘性能测试工程师       薪资20K左右 http://ask.testroad.org/article/4042.上海-交通银行总行-性能测试专家 ...

  5. 7.1 基础知识Android消息处理机制

    1. Android消息处理机制: Handler, MessageQueue, Looper, Thread 线程概念 : 一个应用程序运行时它的主体被称为进程, 一个进程内部可以有多个线程, 线程 ...

  6. zynq+linux+ramdisk can调试

    由于采用ramdisk文件系统,自带的ip工具版本太旧无法配置can,需要自行编译ip,具体参见参考文献2 1.vivado配置ps 2.设备树增加can0,一般开发板均已提供此配置 can@e000 ...

  7. 英特尔投资:7200万美元投资12家创新公司,包括3家中国公司(www.intelcapital.com)

    集微网消息,英特尔投资——英特尔公司全球投资机构,今天在英特尔投资全球峰会上宣布向12家科技创业公司投资超过7200万美元.加上今天宣布的新投资,英特尔投资在2018年投资总额已超过1.15亿美元. ...

  8. php课程 8-28 php如何绘制生成显示图片

    php课程 8-28 php如何绘制生成显示图片 一.总结 一句话总结:gd库轻松解决 1.php图片操作生成的图的两种去向是什么? 一种在页面直接输出,一种存进本地磁盘 2.php操作图片的库有哪些 ...

  9. VC使用ADO连接远程oracle数据库

    _ConnectionPtr pConn;//连接对像 _RecordsetPtr pRect;//记录集对象 _CommandPtr  pCmd;//命令对象 pRect.CreateInstanc ...

  10. php 随机数中奖demo演示

    感谢https://blog.csdn.net/z960339491/article/details/69511491提供的思路,应该是java,于我不合适,写了php <?php // 中奖概 ...