原题链接:https://www.luogu.org/problemnew/show/P3623
其实这题贼jb简单,也不知道为啥是省选的。。。
就是看尽量用鹅卵石能不能用完。。。
再看尽量用水泥能不能用完。。。
就没了。。。
最小生成树搞一下,记得判断联通就行。。。
#include <bits/stdc++.h>
using namespace std;
const int maxn=10005;
struct node
{
int x,y,c;
}a[maxn],ans[maxn];
int f[maxn];
int n,m,k;
int find(int x)
{
if(f[x]==x) return x;
return f[x]=find(f[x]);
}
int cmp1(node x,node y)
{
return x.c>y.c;
}
int cmp2(node x,node y)
{
return x.c<y.c;
}
int check()
{
int cnt=0;
for(int i=1;i<=n;i++) if(f[i]==i) cnt++;
return cnt==1;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);int temp=k;
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++)
{
cin>>a[i].x>>a[i].y>>a[i].c;
}
sort(a+1,a+1+m,cmp1);
int cnt=0;
for(int i=1;i<=m&&cnt<n-1;i++)
{
int x=find(a[i].x),y=find(a[i].y);
if(x==y) continue;
f[x]=y;
if(a[i].c==0) {a[i].c=-1;k--;}
}
if(k<0||!check()) {cout<<"no solution";return 0;}
//如果尽量用水泥路鹅卵石都不够,那就是不行
for(int i=1;i<=n;i++) f[i]=i;cnt=0;
sort(a+1,a+1+m,cmp2);
k=temp;
for(int i=1;i<=m&&cnt<n-1;i++)
{
int x=find(a[i].x),y=find(a[i].y);
if(x==y) continue;
if(a[i].c==1||k>0)
{
ans[++cnt]=a[i];f[x]=y;//如果可以就存一下
if(a[i].c<1) k--,a[i].c=0;
}
}
if(k>0||!check()) {cout<<"no_solution";return 0;}
//如果尽量用鹅卵石路都用不完,那就是不行
for(int i=1;i<=cnt;i++)
{
if(ans[i].c<0) ans[i].c=0;
cout<<ans[i].x<<" "<<ans[i].y<<" "<<ans[i].c<<endl;
}
return 0;
}