cpp
复制代码
#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define endl '\n'
using namespace std;
const int mod=998244353;
typedef pair<int,int>pii;
const int N=3e5+10;
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int num[N],inv[N];//阶乘以及阶乘的逆元
//ans=num[a]*inv[a-b]%mod*inv[b]%mod;
int kmi(int a,int b){
int res=1;
while(b){
if(b&1)res=res*a%mod;
b>>=1;
a=a*a%mod;
}
return res;
}
void init(){
num[0]=1,inv[0]=1;
for(int i=1;i<=3e5;i++){//预处理出2e5内的阶乘以及其逆元
num[i]=num[i-1]*i%mod;
inv[i]=kmi(num[i],mod-2);
}
}
void solve(){
int n,m;cin>>n>>m;
vector<pii>e0,e1,e2;
for(int i=1;i<=m;i++){
int u,v,w;cin>>u>>v>>w;
if(w==0) e0.push_back({u,v});
else if(w==1) e1.push_back({u,v});
else e2.push_back({u,v});
}
vector<pii>ans1,ans2,ans3;
auto ck1=[&]()->bool{
int pos0=0,pos1=0;
bool ok1=0,ok2=0;
vector<int>p(n+10);
for(int i=1;i<=n;i++) p[i]=i;
auto find=[&](auto &&find,int x)->int{
if(x==p[x]) return x;
else return p[x]=find(find,p[x]);
};
auto merge=[&](int a,int b)->bool{
int x=find(find,a),y=find(find,b);
if(x==y) return 0;
if(x>y) swap(x,y);
p[y]=x;
return 1;
};
for(int ct=0;ct<e0.size()+e1.size();ct++){
if(ct%2){
if(pos0<e0.size()){
auto [u,v]=e0[pos0];pos0++;
if(merge(u,v)){
ok1=1;
ans1.push_back({u,v});
}
}
else{
auto [u,v]=e1[pos1];pos1++;
if(merge(u,v)){
ok2=1;
ans1.push_back({u,v});
}
}
}
else{
if(pos1<e1.size()){
auto [u,v]=e1[pos1];pos1++;
if(merge(u,v)){
ok2=1;
ans1.push_back({u,v});
}
}
else{
auto [u,v]=e0[pos0];pos0++;
if(merge(u,v)){
ok1=1;
ans1.push_back({u,v});
}
}
}
}
for(int i=1;i<=n;i++){
if(find(find,i)!=1) return 0;
}
return (ok1&ok2);
};
auto ck2=[&]()->bool{
int pos0=0,pos2=0;
bool ok1=0,ok2=0;
vector<int>p(n+10);
for(int i=1;i<=n;i++) p[i]=i;
auto find=[&](auto &&find,int x)->int{
if(x==p[x]) return x;
else return p[x]=find(find,p[x]);
};
auto merge=[&](int a,int b)->bool{
int x=find(find,a),y=find(find,b);
if(x==y) return 0;
if(x>y) swap(x,y);
p[y]=x;
return 1;
};
for(int ct=0;ct<e0.size()+e2.size();ct++){
if(ct%2){
if(pos0<e0.size()){
auto [u,v]=e0[pos0];pos0++;
if(merge(u,v)){
ok1=1;
ans2.push_back({u,v});
}
}
else{
auto [u,v]=e2[pos2];pos2++;
if(merge(u,v)){
ok2=1;
ans2.push_back({u,v});
}
}
}
else{
if(pos2<e2.size()){
auto [u,v]=e2[pos2];pos2++;
if(merge(u,v)){
ok2=1;
ans2.push_back({u,v});
}
}
else{
auto [u,v]=e0[pos0];pos0++;
if(merge(u,v)){
ok1=1;
ans2.push_back({u,v});
}
}
}
}
for(int i=1;i<=n;i++){
if(find(find,i)!=1) return 0;
}
return (ok2&ok1);
};
auto ck3=[&]()->bool{
int pos1=0,pos2=0;
bool ok1=0,ok2=0;
vector<int>p(n+10);
for(int i=1;i<=n;i++) p[i]=i;
auto find=[&](auto &&find,int x)->int{
if(x==p[x]) return x;
else return p[x]=find(find,p[x]);
};
auto merge=[&](int a,int b)->bool{
int x=find(find,a),y=find(find,b);
if(x==y) return 0;
if(x>y) swap(x,y);
p[y]=x;
return 1;
};
for(int ct=0;ct<e1.size()+e2.size();ct++){
if(ct%2){
if(pos1<e1.size()){
auto [u,v]=e1[pos1];pos1++;
if(merge(u,v)){
ok1=1;
ans3.push_back({u,v});
}
}
else{
auto [u,v]=e2[pos2];pos2++;
if(merge(u,v)){
ok2=1;
ans3.push_back({u,v});
}
}
}
else{
if(pos2<e2.size()){
auto [u,v]=e2[pos2];pos2++;
if(merge(u,v)){
ok2=1;
ans3.push_back({u,v});
}
}
else{
auto [u,v]=e1[pos1];pos1++;
if(merge(u,v)){
ok1=1;
ans3.push_back({u,v});
}
}
}
}
for(int i=1;i<=n;i++){
if(find(find,i)!=1) return 0;
}
return (ok1&ok2);
};
if(ck1()){
for(auto [u,v]:ans1){
cout<<u<<" "<<v<<endl;
}
return;
}
if(ck2()){
for(auto [u,v]:ans2){
cout<<u<<" "<<v<<endl;
}
return;
}
if(ck3()){
for(auto [u,v]:ans3){
cout<<u<<" "<<v<<endl;
}
return;
}
cout<<-1;
}
signed main(){
ios_base::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
// init();
int T=1;//cin>>T;
while(T--){
solve();
cout<<endl;
}
return 0;
}