zoukankan      html  css  js  c++  java
  • cf1027F. Session in BSU(并查集 匈牙利)

    题意

    题目链接

    $n$个人,每个人可以在第$a_i$天或第$b_i$,一天最多考一场试,问在最优的情况下,最晚什么时候结束

    Sol

    自己只能想到暴力匈牙利二分图匹配,然而还是被构造数据卡了。。

    标算很神奇。

    同样考虑把题目中给出的模型建成二分图,左侧代表每个人,右侧代表每一天的考试

    然后我们把右侧每个人能选择的两个点之间连边

    这样模型就由二分图转化成了一条链上的问题。

    分情况讨论一下:

    考虑当前的联通块:

    1、边数大于点数:因为每个条边都必须与一个点匹配,因此这样肯定无解

    2、边数 = 点数:很显然是一棵基环树,输出最大值即可

    3、边数 < 点数:这是一棵树,输出次大值即可

    这样我们用并查集维护一下最大值,次大值。就做完了。。

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<vector>
    #define LL long long 
    using namespace std;
    const int MAXN = 1e6 + 10, INF = 1e9 + 7;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int N;
    int a[MAXN], b[MAXN], date[MAXN << 1], cnt, vis[MAXN], link[MAXN], atk[MAXN];
    vector<int> v[MAXN];
    int Aug(int x, int tim) {
        for(int i = 0; i < v[x].size(); i++) {
            int to = v[x][i];
            if(vis[to] == tim) continue;
            vis[to] = tim;
            if(!link[to] || Aug(link[to], tim)) 
                {
                    link[to] = x; 
                    return 1;
                }
        }
        return 0;
    }
    main() {
        N = read();
        for(int i = 1; i <= N; i++) a[i] = read(), b[i] = read(), date[++cnt] = a[i], date[++cnt] = b[i];
        sort(date + 1, date + cnt + 1);
        cnt = unique(date + 1, date + cnt + 1) - date - 1;
        for(int i = 1; i <= N; i++) {
            a[i] = lower_bound(date + 1, date + cnt + 1, a[i]) - date, 
            b[i] = lower_bound(date + 1, date + cnt + 1, b[i]) - date;        
            v[a[i]].push_back(i);
            v[b[i]].push_back(i);
        }
        int ans = 0, tot = 0;
        for(int i = 1; i <= cnt; i++) {
            if(Aug(i, i)) 
                tot++;
            if(tot == N) {
                printf("%d", date[i]); return 0;
            }        
        }
        puts("-1");
        return 0;
    }
    /*
    3
    23 27
    22 26
    27 30
    */
    暴力匈牙利TLE ON TEST 56
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int MAXN = 2 * 1e6 + 10;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int N, a[MAXN], b[MAXN], date[MAXN << 1], cnt = 0, fa[MAXN], tag[MAXN], mx[MAXN], smx[MAXN];
    int find(int x) {
        if(fa[x] == x) return fa[x];
        else return fa[x] = find(fa[x]);
    }
    int main() {
        N = read();
        for(int i = 1; i <= N; i++) a[i] = read(), b[i] = read(), date[++cnt] = a[i], date[++cnt] = b[i];
        sort(date + 1, date + cnt + 1);
        cnt = unique(date + 1, date + cnt + 1) - date - 1;
        for(int i = 1; i <= N; i++)
            a[i] = lower_bound(date + 1, date + cnt + 1, a[i]) - date,
            b[i] = lower_bound(date + 1, date + cnt + 1, b[i]) - date;
        for(int i = 1; i <= cnt; i++) fa[i] = i, mx[i] = i;
        
        for(int i = 1; i <= N; i++) {
            int x = a[i], y = b[i];
            int fx = find(x), fy = find(y);
            if(find(x) != find(y)) {
                fa[fy] = fx;  tag[fx] |= tag[fy]; 
                if(mx[fy] > mx[fx]) smx[fx] = max(smx[fx], max(smx[fy], mx[fx])), mx[fx] = mx[fy];
                else smx[fx] = max(smx[fx], mx[fy]);
            } 
            else if(!tag[fx]) tag[fx] = 1;
            else {puts("-1"); return 0;}
        }
        int ans = 0;
        for(int i = 1; i <= cnt; i++) {
            if(fa[i] == i)
                if(tag[i]) ans = max(ans, mx[i]);
                else ans = max(ans, smx[i]);
        }
        printf("%d
    ", date[ans]);
        return 0;
    }
  • 相关阅读:
    如何在Dreamweaver中使用emmet(ZenCoding)插件
    向Dreamwearer安装emmet插件时提示“无法更新菜单,将不会安装该扩展”的解决方法
    CSS层模型
    css布局模型
    元素分类
    段落排版--中文字间距、字母间距
    Qt 无边框
    QTimer.singleShot与QWidget初始化
    QNetworkAccessManager使用的简单封装
    Qt中用cJSON解析带中文的QString
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9647223.html
Copyright © 2011-2022 走看看