哎。。。
好几天没有A题了。。
真的感觉很蛋疼,抽了7天去复习。。后来发现其实都玩了。。
这个题还算是比较水
首先我们用并查集先随便的求一个最小生成树
然后把在最小生成树上的0边拿出来,如果大于k那么无解
然后第二次处理的时候把上一步求出来的一定在生成树里的边先加进去
然后再加一些0边,加到k为止,最后再加些1边保证是树就可以了
本题最重要的收获是我学会了新的编程风格啊感觉不错。。!!!!
真的感觉 这种很美观啊。。。但是在调用函数的时候要打空格么很奇怪?求解释。。。。
//begin new type style.....
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAX 100009
#define get_father find
#define rep(i,j,k) for (int i=j; i<=k; i++)
using namespace std;
int num = 0;
int n, m, L=0, R=0, father[MAX], k;
struct wbysr
{
int from,to,done;
}l[MAX], r[MAX];
inline int find (int x)
{
return father[x]==x ? x : father[x] = get_father(father[x]);
}
inline void Union (int x,int y)
{
int fx = get_father(x), fy = get_father(y);
if (fx != fy)
father[fy] = fx;
}
int main()
{
scanf ("%d%d%d", &n, &m, &k);
rep (i, 1, m)
{
int a1,a2,a3;
scanf ("%d%d%d", &a1, &a2, &a3);
if (!a3)
l[++L].from = a1, l[L].to = a2;
else
r[++R].from = a1, r[R].to = a2;
}
rep (i, 1, n)
father[i] = i;
rep (i, 1, R)
if (find(r[i].from) != find(r[i].to))
Union(r[i].from, r[i].to);
rep (i, 1, L)
if (find(l[i].from) != find(l[i].to))
Union(l[i].from, l[i].to), num++, l[i].done = 1;
if (num > k)
{
printf ("no solution\n");
return 0;
}
rep (i, 1, n)
father[i] = i;
rep (i, 1, L)
if (l[i].done)
Union(l[i].from,l[i].to);
rep (i, 1, L)
if (find(l[i].from) != find(l[i].to) && num<k)
Union(l[i].from,l[i].to), num++, l[i].done = 1;
rep (i, 1, R)
if(find(r[i].from) != find(r[i].to))
Union(r[i].from,r[i].to), r[i].done = 1;
rep (i, 1, L)
if(l[i].done)
printf ("%d %d 0\n",l[i].from,l[i].to);
rep (i, 1, R)
if(r[i].done)
printf ("%d %d 1\n",r[i].from,r[i].to);
return 0;
}