• bzoj3624 [Apio2008]免费道路


    Description

    这里写图片描述

    Input

    这里写图片描述

    OutPut

    这里写图片描述

    Sample Input

    5 7 2
    1 3 0
    4 5 1
    3 2 0
    5 3 1
    4 3 0
    1 2 1
    4 2 1

    Sample Output

    3 2 0
    4 3 0
    5 3 1
    1 2 1

    Solution

    失踪人口回归。
    题目大意:求图一棵生成树,使得这棵树里恰好有 (k) 条特殊边。
    两遍 (kruskal) ,第一遍优先加入非特殊边,预处理出有哪些边是非选不可的。第二遍先加入 (k) 条特殊边,再加入非特殊边。判断 (no) (solution)时细节较多,详见代码。

    #include<bits/stdc++.h>
    using namespace std;
    
    #define N 200001
    #define rep(i, a, b) for (int i = a; i <= b; i++)
    #define drp(i, a, b) for (int i = a; i >= b; i--)
    #define No { puts("no solution"); return 0; }
    
    inline int read() {
    	int x = 0, flag = 1; char ch = getchar(); while (!isdigit(ch)) { if (!(ch ^ '-')) flag = -1; ch = getchar(); }
    	while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); return x * flag;
    }
    
    inline void write(int x) {
    	if (!x) { putchar('0'); return; } if (x < 0) putchar('-'), x = -x;
    	char buf[30] = ""; int top = 0; while (x) buf[++top] = x % 10 + '0', x /= 10; while (top) putchar(buf[top--]);
    }
    
    int n, m, K;
    struct edgeType {
    	int u, v, w; bool chos;
    	void outPut() { if (!chos) return; write(u), putchar(' '), write(v), putchar(' '), write(w), puts(""); }
    }eg[N];
    bool cmp(const edgeType& a, const edgeType& b) { return a.w > b.w; }
    
    int fa[20001];
    int find(int x) { return fa[x] ? fa[x] = find(fa[x]) : x; }
    
    int main() {
    	n = read(), m = read(), K = read(); 
    	rep(i, 1, m) eg[i].u = read(), eg[i].v = read(), eg[i].w = read(); sort(eg + 1, eg + 1 + m, cmp);
    	int spCnt = 0;
    	rep(i, 1, m) {
    		int x = find(eg[i].u), y = find(eg[i].v); if (!(x ^ y)) continue;
    		fa[x] = y; if (!eg[i].w) eg[i].chos = 1, spCnt++;
    	}
    	if (spCnt > K) No;
    	memset(fa, 0, sizeof fa); int cnt = 0; spCnt = 0;
    	rep(i, 1, m) if (eg[i].chos) { fa[find(eg[i].u)] = find(eg[i].v); cnt++; spCnt++; continue; }
    	drp(i, m, 1) {
    		if (cnt == n - 1) break; if (eg[i].w && spCnt != K) No;
    		int x = find(eg[i].u), y = find(eg[i].v); if (!(x ^ y) || eg[i].chos) continue;
    		if (!eg[i].w && spCnt < K) fa[x] = y, eg[i].chos = 1, spCnt++, cnt++;
    		else if (eg[i].w) fa[x] = y, eg[i].chos = 1, cnt++;
    	}
    	if (cnt ^ (n - 1)) No;
    	rep(i, 1, m) eg[i].outPut();
    	return 0;
    }
    
  • 相关阅读:
    python学习===从一个数中分解出每个数字
    python学习===复制list
    Jmeter===测试案例参考
    Jmeter==HTTP信息头管理器的作用
    python实战===使用随机的163账号发送邮件
    python实战===实现读取txt每一行的操作,账号密码
    python实战===生成随机数
    python实战===输入密码以******的形式在cmd中展示
    python实战===使用smtp发送邮件的源代码,解决554错误码的问题,更新版!
    python实战===使用smtp发送邮件的源代码,解决554错误码的问题
  • 原文地址:https://www.cnblogs.com/aziint/p/8416246.html
Copyright © 2020-2023  润新知