码迷,mamicode.com
首页 > 其他好文 > 详细

CF538H Summer Dichotomy

时间:2020-01-27 17:29:04      阅读:64      评论:0      收藏:0      [点我收藏+]

标签:++i   二分图   vector   dfs   inline   const   push   pre   include   

Link
如果没有总人数的限制的话,两个班的人数分别为\(R=\min(r_i),L=\max(l_i)\)是最优的。
如果人数超限了就减少\(L\),如果人数不够就增加\(R\)
然后就是个简单的二分图染色判定问题了。

#include<cstdio>
#include<cctype>
#include<vector>
namespace IO
{
    char ibuf[(1<<21)+1],*iS,*iT;
    char Get(){return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++);}
    int read(){int x=0,c=Get();while(!isdigit(c))c=Get();while(isdigit(c))x=x*10+c-48,c=Get();return x;}
}
using IO::read;
int min(int a,int b){return a<b? a:b;}
int max(int a,int b){return a>b? a:b;}
const int N=100007;
std::vector<int>e[N];int l[N],r[N],col[N];
int dfs(int u)
{
    for(int v:e[u]) if(!col[v]) {if(col[v]=3-col[u],!dfs(v)) return 0;} else if(col[u]==col[v]) return 0;
    return 1;
}
int main()
{
    int L=read(),R=read(),n=read(),m=read(),mn=1e9,mx=0;
    for(int i=1;i<=n;++i) mx=max(mx,l[i]=read()),mn=min(mn,r[i]=read());
    if(mn+mx<L) mx=L-mn; else if(mn+mx>R) mn=R-mx;
    if(mn<0||mx<0) return puts("IMPOSSIBLE"),0;
    for(int i=1;i<=n;++i)
    {
    int f1=l[i]<=mn&&mn<=r[i],f2=l[i]<=mx&&mx<=r[i];
    if(!f1&&!f2) return puts("IMPOSSIBLE"),0;
    if(f1&&!f2) col[i]=1;
    if(!f1&&f2) col[i]=2;
    }
    for(int i=1,u,v;i<=m;++i) u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
    for(int i=1;i<=n;++i) if(col[i]&&!dfs(i)) return puts("IMPOSSIBLE"),0;
    for(int i=1;i<=n;++i) if(!col[i]) if(col[i]=1,!dfs(i)) return puts("IMPOSSIBLE"),0;
    puts("POSSIBLE"),printf("%d %d\n",mn,mx);
    for(int i=1;i<=n;++i) printf("%d",col[i]);
}

CF538H Summer Dichotomy

标签:++i   二分图   vector   dfs   inline   const   push   pre   include   

原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12236100.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!