• NOIP2010关押罪犯 二分+二染色


    这个题一上来 没有思路,后来想没有思路就二分吧

    那么我们来二分

    首先,大于当前的mid值的关系,不能出现在一个集合里

    (即关系形成的图是一个二分图,判定二分图可以二染色)

    如果不能形成二分图,那么说明有些关系要在一个集合里,那就向上二分

    否则向下二分

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int>pii;
    const int N=2e4+5;
    const int INF=0x3f3f3f3f;
    int head[N],tot,n,m;
    struct Edge
    {
        int u,v,next;
        bool operator<(const Edge &rhs)const
        {
            return next<rhs.next;
        }
    } edge[N*10],o[N*5];
    void add(int u,int v)
    {
        edge[tot].v=v;
        edge[tot].next=head[u];
        head[u]=tot++;
    }
    int cur[N];
    bool dfs(int u,int f)
    {
        cur[u]=(cur[f]^1);
        for(int i=head[u]; ~i; i=edge[i].next)
        {
            int v=edge[i].v;
            if(v==f||cur[v]==(cur[u]^1))continue;
            if(cur[v]==cur[u])return false;
            if(!dfs(v,u))return false;
        }
        return true;
    }
    bool judge(int x)
    {
        Edge tmp;
        tmp.next=x;
        int pos=upper_bound(o+1,o+1+m,tmp)-o;
        if(pos>m)return true;
        memset(head,-1,sizeof(head)),tot=0;
        memset(cur,-1,sizeof(cur));
        int s;
        for(int i=pos; i<=m; ++i)
            add(o[i].u,o[i].v),add(o[i].v,o[i].u),s=o[i].u;
        for(int i=pos;i<=m;++i){
          int s=o[i].u;
          if(cur[s]!=-1)continue;
          cur[s]=0;
          if(!dfs(s,s))return false;
        }
        return 1;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        if(m==0)
        {
            printf("0
    ");
            return 0;
        }
        for(int i=1; i<=m; ++i)
            scanf("%d%d%d",&o[i].u,&o[i].v,&o[i].next);
        o[0].next=0;
        sort(o+1,o+1+m);
        int l=0,r=m;
        while(l<r)
        {
            int mid=(l+r)>>1;
            if(judge(o[mid].next))r=mid;
            else l=mid+1;
        }
        printf("%d
    ",o[(l+r)>>1].next);
        return 0;
    }
    View Code

       

  • 相关阅读:
    js引用类型赋值不改变原对象值
    VS2017启动实例调试(谷歌浏览器)闪退问题
    ext6时间控件(带时分秒)
    extjs列表中文件上传与下载(带有重命名操作)
    c# word(1) 向标签处添加文字
    关于页面加载后执行使用afterrender
    ExtJS,grid多选框列
    vue起手式
    Javascript诞生与历史
    markdown语法说明
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5451146.html
Copyright © 2020-2023  润新知