传送门:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3624
先做一遍生成树,有多于k个0边就no solution
再把原来选的0边加上,再选一些0边凑够k个
再用1边补满
完了
Code:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct edge{
int u,v;
}edges[maxn];
int fa[maxn];
int n,m,k,cnt;
int front,back;
bool vis[maxn];
int find(int x){
if(fa[x]!=x)return fa[x]=find(fa[x]);return x;
}
int main(){
scanf("%d%d%d",&n,&m,&k);back=m;
for(int i=1;i<=m;i++){
int u,v,c;scanf("%d%d%d",&u,&v,&c);
if(!c)edges[back--]=(edge){u,v};
else edges[++front]=(edge){u,v};
}for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++){
if(find(edges[i].u)!=find(edges[i].v)){
fa[find(edges[i].u)]=find(edges[i].v);
vis[i]=i>front; cnt+=i>front;
}
}if(cnt>k){
puts("no solution");
return 0;
}for(int i=1;i<=n;i++)fa[i]=i;
for(int i=back+1;i<=m;i++)
if(vis[i])fa[find(edges[i].u)]=find(edges[i].v);
for(int i=back+1;i<=m;i++)
if(!vis[i]&&cnt<k&&find(edges[i].u)!=find(edges[i].v))
fa[find(edges[i].u)]=find(edges[i].v),cnt++,vis[i]=1;
if(cnt!=k){
puts("no solution");
return 0;
}
for(int i=1;i<=front;i++)
if(find(edges[i].u)!=find(edges[i].v))
fa[find(edges[i].u)]=find(edges[i].v),vis[i]=1;
for(int i=1;i<=m;i++)if(vis[i])
printf("%d %d %d\n",edges[i].u,edges[i].v,i<=front);
return 0;
}