zoukankan      html  css  js  c++  java
  • UVA

    题目大意:给出一张图,看能形成几个生成树

    解题思路:先推断是否能形成生成树,在推断是否有次小生成树

    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    
    #define N 110
    #define M 410
    #define INF 0x3f3f3f3f
    
    struct Edge{
        int from, to, cost, next;
    }E[M];
    int head[N], d[N], maxcost[N][N], id[M], f[N];
    int tot, n, m;
    bool mark[N], vis[M];
    
    void AddEdge(int u, int v, int c) {
        E[tot].from = u; E[tot].to = v; E[tot].cost = c; E[tot].next = head[u]; head[u] = tot++;
        u = u ^ v; v = u ^ v; u = u ^ v;
        E[tot].from = u; E[tot].to = v; E[tot].cost = c; E[tot].next = head[u]; head[u] = tot++;
    }
    
    void init() {
        memset(head, -1, sizeof(head));
        tot = 0;
    
        scanf("%d%d", &n, &m);
        int u, v, c;
        for (int i = 0; i < m; i++) {
            scanf("%d%d%d", &u, &v, &c);
            AddEdge(u, v, c);
        }
    }
    
    int Prim() {
        for (int i = 1; i <= n; i++)
            d[i] = INF;
        memset(vis, 0, sizeof(vis));
        memset(mark, 0, sizeof(mark));
        d[1] = 0;
        f[1] = 1;
        vector<int> v;
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            int t = INF, x;
            for (int j = 1; j <= n; j++)
                if (!mark[j] && d[j] < t)
                    t = d[x = j];
            if (t == INF) {
                return -1;
            }
    
            mark[x] = true;
            if (x != 1) {
                vis[id[x]] = vis[id[x] ^ 1] = true;
                ans += E[id[x]].cost;
            }
            int size = v.size();
            for (int j = 0; j < size; j++) 
                maxcost[v[j]][x] = maxcost[x][v[j]] = max(maxcost[v[j]][f[x]], E[id[x]].cost);
            v.push_back(x);
    
            for (int j = head[x]; ~j; j = E[j].next) {
                int v = E[j].to;
                if (!mark[v] && E[j].cost < d[v]) {
                    d[v] = E[j].cost;
                    id[v] = j;
                    f[v] = x;
                }
            }
        }
        return ans;
    }
    
    int cas = 1;
    void solve() {
        printf("Case #%d : ", cas++);
        int ans = Prim();
        if (ans == -1) {
            printf("No way
    ");
            return ;
        }
    
        bool flag = false;
        int ans2 = INF, u, v;
        for (int i = 0; i < tot; i += 2) {
            if (!vis[i]) {
                u = E[i].from;
                v = E[i].to;
                ans2 = min(ans2, ans - maxcost[u][v] + E[i].cost);
            }
        }
        if (ans2 == INF) 
            printf("No second way
    ");
        else
            printf("%d
    ", ans2);
    
    }
    
    int main() {
        int test;
        scanf("%d", &test);
        while (test--) {
            init();
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    关于Jupyter Notebook默认起始目录设置无效的解决方法
    关于二叉树中度为0与度为2节点数关系证明
    LeetCode第[3]题(Java):Longest Substring Without Repeating Characters 标签:Linked List
    数据结构,物理结构,存储结构,逻辑结构的区分
    条件变量 sync.Cond
    defer 的常用场景
    switch...case... 语句中的类型转换
    golang 切片和数组在for...range中的区别
    golang 并发顺序输出数字
    Golang 中哪些值是不可以寻址的
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7399571.html
Copyright © 2011-2022 走看看