• 51nod 3 * problem


    1640
    题意:
    一张无向图
    在最小化最大边后求最大边权和
    Slove:
    sort
    最小生成树
    倒叙最大生成树

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <string>
    
    using namespace std;
    
    #define LL long long
    
    #define gc getchar()
    inline int read() {int x = 0, f = 1; char c = gc; 
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = gc;}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x * f;}
    inline LL read_LL() {LL x = 0; char c = gc; while(c < '0' || c > '9') c = gc;
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x;}
    #undef gc
    
    const int N = 1e5 + 10;
    
    int fa[N];
    int A[N << 1], U[N << 1], V[N << 1], W[N << 1];
    int n, m;
    
    bool Cmp(int a, int b) {return W[a] < W[b];}
    
    int Get(int x) {return fa[x] == x ? x : fa[x] = Get(fa[x]);}
    
    void Minst(int &R) {
        for(int i = 1; i <= n; i ++) fa[i] = i;
        int js = 0;
        for(int i = 1; i <= m; i ++) {
            int fu = Get(U[A[i]]), fv = Get(V[A[i]]);
            if(fu != fv) {
                fa[fu] = fv;
                js ++;
            }
            if(js == n - 1) {
                R = i;
                while(W[A[R + 1]] == W[A[i]]) R ++;
                return ;
            }
        }
    }
    
    inline long long Maxst(int R) {
        for(int i = 1; i <= n; i ++) fa[i] = i;
        int js = 0;
        long long ret = 0;
        for(int i = R; i >= 1; i --) {
            int fu = Get(U[A[i]]), fv = Get(V[A[i]]);
            if(fu != fv) {
                fa[fu] = fv;
                ret += W[A[i]];
                js ++;
            }
            if(js == n - 1) return ret;
        }
    }
    
    int main() {
        n = read(), m = read();
        for(int i = 1; i <= m; i ++) A[i] = i, U[i] = read(), V[i] = read(), W[i] = read();
        sort(A + 1, A + m + 1, Cmp);
        int R;
        Minst(R);
        cout << Maxst(R);
        return 0;
    }

    1649
    由于 1 - n 之间一定存在一种直接相连的道路
    判断哪种直接相连
    跑另外一种的最短路

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <string>
    
    using namespace std;
    
    #define LL long long
    
    #define gc getchar()
    inline int read() {int x = 0; char c = gc; while(c < '0' || c > '9') c = gc;
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x;}
    inline LL read_LL() {LL x = 0; char c = gc; while(c < '0' || c > '9') c = gc;
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x;}
    #undef gc
    
    const int N = 410, oo = 999999999;
    
    int Map[N][N], Bmap[N][N];
    int n, m;
    
    int main() {
        n = read(), m = read();
        for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) Map[i][j] = oo;
        for(int i = 1; i <= n; i ++) Map[i][i] = 0;
        for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) Bmap[i][j] = oo;
        for(int i = 1; i <= n; i ++) Bmap[i][i] = 0;
        for(int i = 1; i <= m; i ++) {
            int u = read(), v = read();
            Map[u][v] = Map[v][u] = 1;
        }
        if(Map[1][n] == 1) {
            for(int i = 1; i <= n; i ++) 
                for(int j = 1; j <= n; j ++) {
                    if(i == j) continue;
                    if(Map[i][j] == oo) Bmap[i][j] = 1;
                }
            for(int k = 1; k <= n; k ++)
                for(int i = 1; i <= n; i ++)
                    for(int j = 1; j <= n; j ++)
                        Bmap[i][j] = min(Bmap[i][j], Bmap[i][k] + Bmap[k][j]);
            if(Bmap[1][n] == oo) cout << -1;
            else cout << Bmap[1][n];
        } else {
            for(int k = 1; k <= n; k ++)
                for(int i = 1; i <= n; i ++)
                    for(int j = 1; j <= n; j ++)
                        Map[i][j] = min(Map[i][j], Map[i][k] + Map[k][j]);
            if(Map[1][n] == oo) cout << -1;
            else cout << Map[1][n];
        }
        return 0;
    }

    1535
    图是树的充要条件
    $m = n - 1$ && 图联通
    由于题目无自环
    所以不存在二元环
    并且若 $m >= n - 1$
    则图联通
    此时若 $m = n$
    那么就会存在且只存在一个三元环(或更大)
    因此只需判断 $n = m$ 即可

    if(n == m) cout << "FHTAGN!";
    else cout << "NO";
  • 相关阅读:
    浅谈异或运算^的作用
    牛客网剑指offer第40题——数组中只出现一次的数字(浅谈位运算的妙用)
    归并排序——一文吃透归并和递归的思想和完整过程!(没看懂请留言)
    深入分析二分查找及其变体
    vector构造函数的学习
    牛客网剑指offer第34题——找到第一个只出现一次的字符
    牛客网剑指offer第27题——求字符串的全排列
    牛客网剑指offer第20题——定义栈的数据结构
    C++重载运算简介
    Leetcode中字符串总结
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9591918.html
Copyright © 2020-2023  润新知