ICPC WF Moscow Invitational Contest(Kingdom of Islands-枚举子集)
Posted nike0good
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ICPC WF Moscow Invitational Contest(Kingdom of Islands-枚举子集)相关的知识,希望对你有一定的参考价值。
给
1
1
1个
n
≤
1
e
5
n\\le 1e5
n≤1e5个点的图,每个点有权值
s
i
s_i
si。若
2
2
2个点
s
i
s_i
si不同,则连边,否则不连边。
有
k
≤
20
k \\le 20
k≤20个特例:原来连边变成不连,或者不连变成连。
求最大完全子图
如果没有特例点,每个
s
i
s_i
si取一个点即可。
考虑有特例的情况:
两个点从连边变成不连:枚举哪个点不在子图中
两个点从不连边变成连:枚举是否两个点都在子图中
剩下贪心
#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i>0;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) \\
For(j,m-1) cout<<a[i][j]<<' ';\\
cout<<a[i][m]<<endl; \\
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b)return (a*b)%F;
ll add(ll a,ll b)return (a+b)%F;
ll sub(ll a,ll b)return ((a-b)%F+F)%F;
void upd(ll &a,ll b)a=(a%F+b%F)%F;
inline int read()
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) if (ch=='-') f=-1; ch=getchar();
while(isdigit(ch)) x=x*10+ch-'0'; ch=getchar();
return x*f;
#define MAXN (100000+10)
#define MAXM (21)
int P,n;
int s[MAXN];
int c[MAXN];
int k;
int u[MAXM],v[MAXM];
map<pair<int,int>,int > h;
bool check(vi v,vi ban)
int sz=SI(v);
Rep(i,sz) Fork(j,i+1,sz-1)
int x=v[i],y=v[j];
// cout<<(s[x]!=s[y])<<' '<<(h.count(mp(x,y))) <<endl;
if((s[x]!=s[y]) ==(h.count(mp(x,y))>0) ) return 0;
return 1;
int t_ck[MAXN]=,clo=0;
bool is_ck[MAXN]=;
bool is_ban[MAXN]=;
int main()
// freopen("k.in","r",stdin);
// freopen(".out","w",stdout);
// cin.tie(0)->sync_with_stdio(0);
P=read(),n=read();
For(i,n) s[i]=read(),c[s[i]]++;
k=read();
Rep(i,k) u[i]=read(),v[i]=read(),h[mp(u[i],v[i])]=h[mp(v[i],u[i])]=1;
int S=1<<k;
int ans=0;
vi ex1,ba1;
Rep(st,S)
vi exist,ban;
++clo;
Rep(i,k)
bool fl=(st>>i)&1;
int u=::u[i],v=::v[i];
if(s[u]==s[v])
if(fl)
exist.pb(u);
exist.pb(v);
t_ck[u]=t_ck[v]=clo;
else
if(fl)
ban.pb(u);
else ban.pb(v);
sort(ALL(exist));
exist.erase(unique(ALL(exist)),exist.end() );
sort(ALL(ban));
ban.erase(unique(ALL(ban)),ban.end() );
bool flag=0;
for(auto p:ban) if(t_ck[p]==clo) flag=1;break;
if(flag) continue;
else if(!check(exist,ban)) continue;
else
int z=0;
for(auto x:exist)
int p=s[x];
if(c[p]>0) ++z;
c[p]-=1e7;
for(auto x:ban)
int p=s[x];
--c[p];
z+=c[p]==0;
z=SI(exist)+P-z;
if(ans<z)
ans=z;
ex1.assign(exist.begin(),exist.end());
ba1.assign(ban.begin(),ban.end());
// ans=max(ans,z);
for(auto x:ban)
int p=s[x];
++c[p];
for(auto x:exist)
int p=s[x];
c[p]+=1e7;
cout<<ans<<endl;
for(auto x:ex1)
is_ck[s[x]]=1;
for(auto x:ba1)
is_ban[x]=1;
For(i,n) if(!is_ban[i] && is_ck[s[i]]==0)
is_ck[s[i]]=1;
ex1.pb(i);
int sz=SI(ex1);
Rep(i,SI(ex1))
cout<<ex1[i];
putchar(i<sz-1?' ':'\\n');
// for(auto x:ex1) cout<<x<<' ';
return 0;
以上是关于ICPC WF Moscow Invitational Contest(Kingdom of Islands-枚举子集)的主要内容,如果未能解决你的问题,请参考以下文章
ICPC WF Moscow Invitational Contest(Kingdom of Islands-枚举子集)
2017-2018 ACM-ICPC, NEERC, Moscow Subregional Contest
2016-2017 ACM-ICPC, NEERC, Moscow Subregional Contest Problem L. Lazy Coordinator
2014-2015 ACM-ICPC, NEERC, Moscow Subregional Contest B - Bring Your Own Bombs 离散化+扫描线+计算期望