• 【BZOJ3624】免费道路


    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3624


    坑!!!

    先注明,输出no solution时也要换行,不换不对,别问我怎么知道的。

    思路巧妙,值得学习。我们要保留k条鹅卵石路,可以优先添加水泥路,从而确定哪些鹅卵石路是必须添加的。

    若添加完一遍,发现找不到n-1条边,说明图不连通,输出no solution ;若必须添加的鹅卵石路多于k条,说明无解,输出no solution 。

    然后我们先把必须添加的鹅卵石路添加上,不足k条就优先从鹅卵石路中补上,若补不齐,说明无解,输出no solution 。

    最后输出答案即可。

     1 #include <cstdio>
     2 #include <algorithm>
     3 
     4 using namespace std;
     5 
     6 inline int get_num() {
     7     int num = 0;
     8     char c = getchar();
     9     while (c < '0' || c > '9') c = getchar();
    10     while (c >= '0' && c <= '9')
    11         num = num * 10 + c - '0', c = getchar();
    12     return num;
    13 }
    14 
    15 const int maxn = 2e4 + 5, maxm = 1e5 + 5;
    16 
    17 struct Edge {
    18     int u, v, c;
    19     bool operator < (const Edge& rhs) const {
    20         return c > rhs.c;
    21     }
    22 } edge[maxm];
    23 
    24 int fa[maxn], need[maxn], neid, ans[maxn], aeid;
    25 
    26 int dj_find(int i) {
    27     if (i == fa[i]) return i;
    28     else return fa[i] = dj_find(fa[i]);
    29 }
    30 
    31 inline void dj_merge(int a, int b) {
    32     fa[dj_find(a)] = dj_find(b);
    33 }
    34 
    35 int main() {
    36     int n = get_num(), m = get_num(), k = get_num();
    37     for (int i = 1; i <= m; ++i) {
    38         edge[i].u = get_num();
    39         edge[i].v = get_num();
    40         edge[i].c = get_num();
    41     }
    42     sort(edge + 1, edge + m + 1);
    43     for (int i = 1; i <= n; ++i) fa[i] = i;
    44     for (int i = 1; i <= m; ++i) {
    45         int u = edge[i].u, v = edge[i].v;
    46         if (dj_find(u) != dj_find(v)) {
    47             dj_merge(u, v);
    48             ans[++aeid] = i;
    49             if (!edge[i].c) need[++neid] = i;
    50         }
    51     }
    52     if (neid > k || aeid != n - 1) {printf("no solution
    "); return 0;}
    53     for (int i = 1; i <= n; ++i) fa[i] = i;
    54     aeid = 0;
    55     for (int i = 1; i <= neid; ++i) {
    56         int u = edge[need[i]].u, v = edge[need[i]].v;
    57         dj_merge(u, v);
    58         ans[++aeid] = need[i];
    59     }
    60     int cnt = neid;
    61     for (int i = m; i >= 1; --i) {
    62         if (cnt == k && !edge[i].c) continue;
    63         int u = edge[i].u, v = edge[i].v;
    64         if (dj_find(u) != dj_find(v)) {
    65             dj_merge(u, v);
    66             if (!edge[i].c) ++cnt;
    67             ans[++aeid] = i;
    68         }
    69     }
    70     if (cnt < k) {printf("no solution
    "); return 0;}
    71     for (int i = 1; i <= aeid; ++i)
    72         printf("%d %d %d
    ", edge[ans[i]].u, edge[ans[i]].v, edge[ans[i]].c);
    73     return 0;
    74 }
    AC代码
  • 相关阅读:
    fms服务器端呼叫客户端
    Linux C取整的方法
    fms客户端呼叫服务器端
    Tree Control DataProviders
    IE7下的css style display的兼容处理
    Maxthon,TheWorld,MyIE等多标签浏览器的Flash缓存问题
    Android深入浅出系列之实例应用—弹出消息Toast对象的使用纯文本方式(一)
    C#温故而知新学习系列之XML编程—Xml读取器XmlReader类(二)
    一步一个脚印学习WCF系列之WCF概要—生成元数据与代理(五)
    Eclipse 常用快捷键(转)
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9905043.html
Copyright © 2020-2023  润新知