• bzoj4078


    二分+2-sat

    枚举第一个权值,二分第二个权值,然后2-sat检查,当第一个权值已经不能形成二分图时,再往下没意义,因为没法分成两个点集。(双指针好像跑得慢)

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 410;
    struct edge {
        int u, v, w;
        edge(int u = 0, int v = 0, int w = 0) : u(u), v(v), w(w) {}
        bool friend operator < (edge A, edge B)
        {
            return A.w > B.w;
        } 
    } e[N * N];
    int n, tot, cnt, all, top, ans;
    int dfn[N], low[N], st[N], belong[N], vis[N], Map[N][N], color[N], fa[N], d[N];
    vector<int> G[N], g[N];
    int find(int x)
    {
        if(fa[x] == x) return x;
        int ret = find(fa[x]);
        d[x] ^= d[fa[x]];
        return fa[x] = ret;
    }
    void tarjan(int u)
    {
        dfn[u] = low[u] = ++cnt;
        st[++top] = u;
        vis[u] = 1;
        for(int i = 0; i < G[u].size(); ++i)
        {
            int v = G[u][i];
            if(!dfn[v]) 
            {
                tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else if(vis[v]) low[u] = min(low[u], low[v]);
        }
        if(low[u] == dfn[u])
        {
            ++all;
            int j;
            while(1)
            {
                j = st[top];
                belong[j] = all;
                vis[j] = 0;
                --top;
                if(j == u) break;
            }
        }
    }
    bool check(int x, int y)
    {
        memset(dfn, 0, sizeof(dfn));
        memset(low, 0, sizeof(low));
        memset(vis, 0, sizeof(vis));
        top = 0;
        cnt = 0; 
        all = 0;
        if(x > y) swap(x, y);
        for(int i = 1; i <= 2 * n; ++i) 
            G[i].clear();
        for(int i = 1; i <= tot; ++i)
        {
            if(e[i].w > y)
            {
                G[e[i].u].push_back(e[i].v + n);
                G[e[i].v].push_back(e[i].u + n);
                G[e[i].u + n].push_back(e[i].v);
                G[e[i].v + n].push_back(e[i].u);
            }
            else if(e[i].w > x)
            {
                G[e[i].u].push_back(e[i].v + n);
                G[e[i].v].push_back(e[i].u + n);
            }    
        }
        for(int i = 1; i <= 2 * n; ++i) if(!dfn[i]) tarjan(i);
        for(int i = 1; i <= n; ++i) if(belong[i] == belong[i + n]) return false;
        return true;
    }
    int main()
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i) fa[i] = i;
        for(int i = 1; i < n; ++i)
            for(int j = 1; j <= n - i; ++j)
            {
                scanf("%d", &Map[i][i + j]);
                e[++tot] = edge(i, i + j, Map[i][i + j]);
            } 
        if(n == 1)
        {
            puts("0");
            return 0;
        }
        ++tot;
        sort(e + 1, e + tot + 1);
        ans = 2000000010;
        int j = tot;
        for(int i = 1; i <= tot && i <= j; ++i)
        {
            while(j && !check(e[i].w, e[j].w)) --j;
            int u = find(e[i].u), v = find(e[i].v);
            if(u != v)
            {
                ans = min(ans, e[i].w + e[j].w);
                d[u] = d[e[i].u] ^ d[e[i].v] ^ 1;
                fa[u] = v;
            }
            else if(d[e[i].u] == d[e[i].v])
            {
                ans = min(ans, e[i].w + e[j].w);
                break;
            }
        }
        printf("%d
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    安装git工具在ubuntu系统
    Ubuntu 16.04安装JDK并配置环境变量-【小白版】
    【gRPC使用问题4】
    【gRPC使用问题3】生成出来无法识别Google.Api.AnnotationsReflection.Descriptor
    LNMP
    Centos下安装Mysql
    yum方式安装的Apache目录详解和配置说明
    Centos下 yum方式安装LAMP
    CentOS配置网易163 yum源
    Apache主配置文件httpd.conf 详解
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7157887.html
Copyright © 2020-2023  润新知