zoukankan      html  css  js  c++  java
  • Gym 102055B Balance of the Force

    https://blog.csdn.net/lalalafloat/article/details/103056764?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163635050916780255222938%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=163635050916780255222938&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_v29-8-103056764.pc_v2_rank_blog_default&utm_term=%E7%BA%BF%E6%AE%B5%E6%A0%91&spm=1018.2226.3001.4450

    (二分图染色 + 联通块 + 线段树)

    #include<bits/stdc++.h>
    #define inf 1e18
    #define ll long long 
    #define int long long 
    #define ull unsigned long long 
    #define PI acos(-1.0)
    #define PII pair<int,int>
    #define lowbit(x) (x & (-x))
    using namespace std;
    const int N = 1e6+7, M = N * 4;
    int x,y,n,m;
    int b_vis[N];
    int col[N];
    int a[N][2],vis[N][2];
    int h[N],nxt[M],e[M],idx;
    struct node{
        int l,r;
        int v;
    }tr[N*4];
    void pushup(int u){
        tr[u].v=min(tr[u<<1].v,tr[u<<1|1].v);
    }
    void build(int u,int l,int r){
        tr[u]={l,r,(ll)inf};
        if(l==r)    return ;
        int mid = l+r >>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
    }
    //    modify(1,seg[i].id,seg[i].min);
    void modify(int u,int x,int v){
        if(tr[u].l==tr[u].r){
            if(tr[u].v==inf)tr[u].v = v;
            else            tr[u].v = max(tr[u].v,v);
            return ;
        } 
        int mid = tr[u].l + tr[u].r >>1;
        if(x<=mid)    modify(u<<1,x,v);
        else        modify(u<<1|1,x,v);
        pushup(u);
    }
    struct bb{
        int min,max,id;
        bool operator < (const bb &rhs)const{
            return max < rhs.max;
        }
    }seg[N<<1];
    void add(int u,int v){
        e[++idx]=v;
        nxt[idx] = h[u];
        h[u] = idx;
    }
    bool dfs(int u,int c){
        col[u] = c;
        for(int i=h[u];i;i=nxt[i]){
            int v= e[i];
            if(col[v] == -1){
                if(!dfs(v,!c))    return false;
            }
            else if(col[v]==c)    return false;
        }
        return true;
    }
    void dfs2(int x,int c,int num){
        vis[x][c]=1;
        seg[num].min=min(seg[num].min,a[x][c]);
        seg[num].max=max(seg[num].max,a[x][c]);
        for(int i=h[x];i;i=nxt[i]){
            int v = e[i];
            if(vis[v][c^1])continue;
            dfs2(v,c^1,num);
        }
    }
    void solve(){
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;++i)h[i]=0;
        for(int i=1;i<=m;++i){
            scanf("%lld%lld",&x,&y);
            add(x,y);add(y,x);
        }
        for(int i=1;i<=n;++i){
            scanf("%lld%lld",&a[i][0],&a[i][1]);
        }
        int block = 0;//联通块数 
        
        //染色 判断是否存在方案 
        int flag=true;
        for(int i=0;i<=n;++i)    col[i]=-1; 
        for(int i=1;i<=n;++i)
            if(col[i]==-1){
                if(dfs(i,0)==false)    flag=false;
                block++;
            }
        if(flag==false){//染色失败 
            printf("IMPOSSIBLE
    ");
            return ;
        }
        //cout<<"ok
    ";
        for(int i=1;i<=block*2;++i){//块信息清空 
            seg[i].max=0;seg[i].min=inf;
            b_vis[i]=0;
        } 
        int cnt = 0;
        for(int i=1;i<=n;++i)    vis[i][0]=0,vis[i][1]=0;//划块路径清空 
        for(int i=1;i<=n;++i){
            if(vis[i][0]==0){
                dfs2(i,0,++cnt);//划分块 
                dfs2(i,1,++cnt);
                seg[cnt-1].id=cnt/2;
                seg[cnt].id=cnt/2;
            } 
        }
        sort(seg+1,seg+1+cnt);
        build(1,1,block);
        int ans = inf;
        int b_cnt = 0;//更新时已用过的块 
        for(int i=1;i<=cnt;++i){
            if(b_vis[seg[i].id]==0){
                b_cnt++;
                b_vis[seg[i].id]=1;
            }
            //线段树修改
            modify(1,seg[i].id,seg[i].min);
            if(b_cnt==block)ans = min (ans,seg[i].max-tr[1].v); 
            //        cout<<seg[i].max<<"    ==   "<<tr[1].v<<"
    ";
        }
        printf("%lld
    ",ans);
    }
    signed main(){
        int t=1;
        scanf("%lld",&t);
        for(int _=1;_<=t;++_){
            printf("Case %lld: ",_);
            solve();
        }
        return 0;
    }
  • 相关阅读:
    I
    H
    G
    F
    E
    论js里面的for循环
    js常见问题之为什么点击弹出的i总是最后一个
    array类型的方法
    string类型的方法
    for in在对象和数组中的应用
  • 原文地址:https://www.cnblogs.com/PdrEam/p/15523883.html
Copyright © 2011-2022 走看看