meaning of the title
Sol
The first answer must be a tree
There are some 0 sides on this tree that must be selected. Let's find them first. If the number $\ geqslant k $, it is obvious that there is no solution
Then consider adding the edge of 0 to it, and judge whether it can be added to k
The specific methods are as follows:
First, let 1 make a spanning tree before it, and the 0 side added must be selected
Let 0 side make a spanning tree in front of us. At this time, we don't need to consider whether we can generate a tree at last, just whether we can add k-pieces
My idea: first of all, the 0 sides that must be selected must be counted, and then all the remaining 0 sides will be added at one time. Obviously, there will be many useless ones. If the number of added sides $< K $, there will be no solution,
Otherwise, consider deleting some 0 sides. LCT maintains the number of 0 sides on each ring after forming a ring. If the number of 0 sides on the ring $> 0 $, subtract one, and add the 1 side. Otherwise, it will not be added. If the total number of 0 sides is k,
Add the remaining edge directly, and finally judge whether a tree can be formed. Otherwise, the number of zero sides is more than k, and prove that there is no solution.
It should be right, but I won't write it even if I'm killed.....
#include<cstdio> #include<algorithm> #define LL long long using namespace std; const int MAXN = 3 * 1e5 + 10, INF = 1e9 +10; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, M, K, num, mt, fa[MAXN]; struct Edge { int u, v, w, f; bool operator < (const Edge &rhs) const {return w > rhs.w;} }E[MAXN]; void AddEdge(int x, int y, int z) {E[++num] = (Edge) {x, y, z};} int comp(const Edge &a, const Edge &b) {return a.w < b.w;} int find(int x) {return fa[x] == x ? fa[x] : (fa[x] = find(fa[x]));} int calc() { int ans = 0; for(int i = 1; i <= num; i++) if(E[i].f) ans++; return ans; } int Kruskal(int opt) { if(opt == 1) sort(E + 1, E + num + 1); else sort(E + 1, E + num + 1, comp); for(int i = 1; i <= N; i++) fa[i] = i; int cnt = 0; if(opt == 2) for(int i = 1; i <= num; i++) if(E[i].f) fa[find(E[i].u)] = find(E[i].v), cnt++; for(int i = 1; i <= num; i++) { int x = E[i].u, y = E[i].v, w = E[i].w; int fx = find(x), fy = find(y); if(fx == fy) continue; if(opt == 1) { if(w == 0) E[i].f = 1; if((++cnt) == N - 1) return calc(); } else if(opt == 2) { cnt++; E[i].f = 1; if(cnt == K) return 1; } else if(opt == 3) { if(w == 0 && (!E[i].f)) continue; if((++cnt <= N - 1)) printf("%d %d %d\n", x, y, w); } fa[fx] = fy; } return 0; } int main() { N = read(); M = read(); K = read(); for(int i = 1; i <= M; i++) { int x = read(), y = read(), z = read(); AddEdge(x, y, z); //AddEdge(y, x, z); } if(Kruskal(1) > K) {puts("no solution"); return 0;} if(!Kruskal(2)) {puts("no soltion"); return 0;} Kruskal(3); return 0; }