传送门:
http://codeforces.com/problemset/problem/605/B
题意:
给定m条边的权值和标志位,标志位为1说明其在最小生成树上,然后还原整个图,如果不行的话就输出-1!!!!!!!!
就是喜欢这种构造题目!!!!
So easy 的题目嘛,只需要把边按照权值从小到大排序,然后顺着往后加不就可以了嘛,如果不在最小生成树上,就隔着加,为-1的情况就是隔着的那个点还没被最小生成树覆盖到嘛!!!
想用高端方式去写,刚开始下标居然搞错了,然后,一定要注意风格与格式,vector时候要push_back,不是直接存
wrong on 7 ,因为排序的时候用vector还是不太方便,因为要保证先遍历的是最小生成树上的边,所以还是默默去开node吧。。。
又wrong on27了,简直是醉了,这次是因为我每次加的时候把是l不动,
r++,这样的话绝对就会出问题啊,会把还没判到的r加进去,结果就变成无解了,简直是醉了。。。。。。
肯定得是r不动,然后l++啊,这样才能保证在已经定了的区间里面进行加和减嘛!!!
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct node{
int value,flag,id;
}a[maxn];
int n,m;
pair<int,int>ans[maxn];
bool cmp(node a,node b){
if(a.value==b.value) return a.flag>b.flag;
return a.value<b.value;
}
int vis[maxn];
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
scanf("%d%d",&a[i].value,&a[i].flag);
a[i].id=i;
}
sort(a+1,a+1+m,cmp);
int cur=1;int l=1;int r=l+2;
for(int i=1;i<=m;i++){
if(a[i].flag==1){
ans[a[i].id].first=cur++;vis[cur-1]=1;
ans[a[i].id].second=cur;vis[cur]=1;
}
else{
if(!vis[r]) return puts("-1");
ans[a[i].id].first=l;
ans[a[i].id].second=r;
l++;
if(l==r-1){
l=1;r++;
}
}
}
for(int i=1;i<=m;i++){
printf("%d %d\n",ans[i].first,ans[i].second);
}
return 0;
}