[Poj]-1679-The Unique MST-N久没写代码的后果╮( ̄▽ ̄)╭

来源:互联网 发布:excel办公软件 编辑:程序博客网 时间:2024/06/05 05:38

NOIP后好久没写代码了,恶补了一个月的文化课感觉自己萌萌哒ˉ﹃ˉ
翻了翻暑假的PPT,都™的是省选++的题,丧心病狂
QQ上和zrt大神和gmh大神聊了聊,感觉自己差的东西好多╮( ̄▽ ̄)╭
=====再扯就写不完了=====分割线=====

原题链接

题意就是给你一个图,判断最小生成树是否是唯一的

很容易想到的就是看看是否存在非严格次小生成树,就可以判断最小生成树是否唯一。

但是更容易想到的是对Kruskal算法进行变形。Kruskal算法的本质是贪心。它每次贪心找到长度最小的边,判断能否合并两个不同的集合。假设能合并x、y两个集合,此时向后搜寻长度与当前边相等的边,判断其端点是否也分别属于x、y两个集合。如果是,那么合并这两个集合就有了两种方法——选择这两条边都可以。那么MST就不唯一。

很简单的题,手太生了,打了快两个小时才写好,蒟蒻就是蒟蒻啊╮( ̄▽ ̄)╭

#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<vector> #define usefile freopen("in", "r", stdin);\freopen("out", "w", stdout);#define maxn 110 using namespace std; struct node{    int f, t, e;}; vector<node> g; int set[maxn], n, m, T, ans, same; //n is nodes m is edges bool cmp(node a, node b){    return a.e < b.e;} inline void all_clear(){    ans = same = 0;    g.clear();    for (int i = 0; i < maxn; i++)        set[i] = i;    return ;} int find_set(int x){    return x == set[x] ? x : set[x] = find_set(set[x]);} inline void union_set(int a, int b){    int x = find_set(a), y = find_set(b);    if (x == y)        return ;    set[x] = y;    return ;} inline void init(){    scanf("%d %d", &n, &m);    int f, t, e;    for (int i = 0; i < m; i++)    {        scanf("%d %d %d", &f, &t, &e);        g.push_back((node){f, t, e});    }    sort(g.begin(), g.end(), cmp);    return ;} inline void kruskal(){    int x, y;    for (int i = 0; i < m; i++)    {        x = find_set(g[i].f);        y = find_set(g[i].t);        if (x != y)        {            ans += g[i].e;            //printf("add edge %d %d %d\n", g[i].f, g[i].t, g[i].e);            for (int j = i + 1; j < m; j++)            {                if (g[j].e == g[i].e && ((find_set(g[j].f) == x && find_set(g[j].t) == y) || (find_set(g[j].f) == y && find_set(g[j].t) == x))) //这里判断了是否存在边连接相同两个集合并且边权相等,注意这里的两个边可能是同向的,也可能是反向的。                {                //  printf("edge %d %d %d is the same with edge %d %d %d\n", g[i].f, g[i].t, g[i].e, g[j].f, g[j].t, g[j].e);                    same = 1;                    return ;                }                if (g[j].e > g[i].e)                    break;            }            union_set(find_set(g[i].f), find_set(g[i].t));        }    }    return ;} int main(){    //usefile    scanf("%d", &T);    while (T--)    {        all_clear();        init();        kruskal();        if (same)            printf("Not Unique!\n");        else            printf("%d\n", ans);    }    return 0;}


0 0