• [洛谷P1525] 关押罪犯


    题目链接:##

    传送门

    题目分析:##

    由最后划分的结果在两个集合,联想到二分图
    又由于答案具有单调性,即如果当前答案可以则更大的答案也一定可以,想到二分答案
    思路:
    二分答案,每次对于答案进行检验,检验时将(<=)答案的边都忽略掉,只保留比答案大的边,然后进行染色判定二分图,如果能构成二分图,说明这些点可以被分在两个不同的集合,且由二分图的定义可以得到,集合内的点之间无连边,而两集合之间的连边在本题的背景下等于被断掉了,即可以保证有分配方案使得冲突值小于二分到的答案

    代码:##

    #include<bits/stdc++.h>
    #define N 50010
    #define M 200010
    using namespace std;
    inline int read() {
        int cnt = 0, f = 1; char c;
        c = getchar();
        while (!isdigit(c)) {
            if (c == '-') f = -f;
            c = getchar();
        }
        while (isdigit(c)) {
            cnt = cnt * 10 + c - '0';
            c = getchar();
        }
        return cnt * f;
    }
    int first[N], nxt[M], to[M], w[M], tot, Max = -1, ans;
    int color[N];
    int n, m, x, y, z;
    void add(int x, int y, int z) {
        nxt[++tot] = first[x];
        first[x] = tot;
        to[tot] = y;
        w[tot] = z;
    }
    bool Dfs (int u, int t) {
        for (register int i = first[u]; i; i = nxt[i]) {
            if (w[i] <= t) continue;
            int v = to[i];
            if (!color[v]) {
                color[v] = 3 - color[u];
                if(!Dfs(v, t)) return false;
            }
            else if (color[v] == color[u]) return false;
        }
        return true;
    }
    bool check (int res) {
        memset(color, 0, sizeof(color));
        bool flag = true;
        for (register int i = 1; i <= n; i++) {
            if (!color[i]) {
                color[i] = 1;
                if(!Dfs(i, res)) {
                	flag = false;
                	break;
                }
            }
        }
        return flag;
    }
    int solve(int r) {
        int l = 0;
        while (l < r) {
            int mid = (l + r) >> 1;
            if (check(mid)) r = mid;
            else l = mid + 1;
        }
        return l;
    }
    int main() {
        n = read(); m = read();
        for (register int i = 1; i <= m; i++) {
            x = read(); y = read(); z = read();
            add(x, y, z);
            add(y, x, z);
            if (z > Max) Max = z;
        }
        ans = solve(Max);
        printf("%d", ans);
        return 0;
    }
    
  • 相关阅读:
    图像
    链接
    列表
    常见的文本标签
    注释有哪些作用?你会用使用注释来做什么?
    如何使用浏览器查看源代码?查看源码的快捷方式是什么?
    编辑HTML源代码
    <html>,<head>,<body>,<title>的作用
    HTML中的标签和属性
    记录Git的安装过程
  • 原文地址:https://www.cnblogs.com/kma093/p/10807671.html
Copyright © 2020-2023  润新知