題目鏈接:點擊打開鏈接
n個點, m條邊, 給出m條邊的權值以及是否在最小生成樹中, 如果可以還原最小生成樹, 則按照順序輸出各邊, 否則輸出-1.
考慮這樣一種構造方法, 首先對邊的權值進行排序, 如果當前邊在最小生成樹中, 直接將頂點加入. 否則, 爲當前邊分配頂點, 由於給在最
小生成樹的邊分配頂點時, 採用了(a, a + 1)這樣的分配方式, 所以給不在最小生成樹分配頂點時要避免這種方式, 加入判斷條件即可.
AC代碼:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "queue"
#include "stack"
#include "cmath"
#include "utility"
#include "map"
#include "set"
#include "vector"
#include "list"
#include "string"
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 5;
int n, m, x, y, z, last;
pair<int, int> ans[MAXN];
vector<pair<pair<int, int>, int > > v;
int main(int argc, char const *argv[])
{
scanf("%d%d", &n, &m);
for(int i = 0; i < m; ++i) {
scanf("%d%d", &x, &y);
v.push_back(make_pair(make_pair(x, !y), i));
}
sort(v.begin(), v.end());
x = 2, y = 0, last = 1;
for(int i = 0; i < v.size(); ++i) {
if(!v[i].first.second) {
ans[v[i].second] = make_pair(last, last + 1);
last++;
}
else {
y++;
if(x == y + 1) {
x++;
y = 1;
}
if(x > last) {
printf("-1\n");
return 0;
}
ans[v[i].second] = make_pair(y, x);
}
}
for(int i = 0; i < m; ++i)
printf("%d %d\n", ans[i].first, ans[i].second);
return 0;
}