标签:++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]);
}
标签:++i 二分图 vector dfs inline const push pre include
原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12236100.html