P9726 [EC Final 2022] Magic
lizhiqing1221 · · 题解
“这不是简单题吗,为什么是黑啊?”——marblue
记位置
发现题目保证
是 luogu 上的倒数第二劣解,不知道为什么 dinic 这么慢啊,可能复杂度假了?
证明一下为什么找到独立集后一定有对应解。无解当且仅当对于区间执行顺序的先后限制构成环。考虑找到这个环上随便一个区间
#include<bits/stdc++.h>
using namespace std;
const int inf=1e9;
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-48;ch=getchar();}
return x*f;
}
int n,S,T,dep[10005];bitset<10005>g[10005];
int bfs(){
for(int i=1;i<=T;i++)dep[i]=0;
dep[S]=1;queue<int>q;q.push(S);
while(!q.empty()){
int u=q.front();q.pop();
for(int v=g[u]._Find_first();v<=T;v=max(v+1,(int)g[u]._Find_next(v))){
if(g[u][v]==0)continue;
if(!dep[v])dep[v]=dep[u]+1,q.push(v);
}
}
return dep[T];
}
int dinic(int u,int flow){
if(u==T)return flow;
int rest=0;
for(int v=g[u]._Find_first();v<=T&&flow;v=max(v+1,(int)g[u]._Find_next(v))){
if(g[u][v]==0)break;
if(dep[v]!=dep[u]+1)continue;
int k=dinic(v,min(flow,1));if(!k)dep[v]=0;
rest+=k,flow-=k;if(k)g[u][v]=0,g[v][u]=1;
}
return rest;
}
int l[5005],r[5005],pos[10005];
signed main(){
n=read(),S=2*n+1,T=2*n+2;
for(int i=1;i<=n;i++){
l[i]=read(),r[i]=read();
pos[l[i]]=0,pos[r[i]]=1;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(l[i]<l[j]&&l[j]<r[i]&&r[i]<r[j]){
g[l[j]][r[i]]=1;
}
}
}
for(int i=1;i<=2*n;i++)if(pos[i]==0)g[S][i]=1;
for(int i=1;i<=2*n;i++)if(pos[i]==1)g[i][T]=1;
int ans=2*n;
while(bfs())ans-=dinic(S,inf);
printf("%d\n",ans);
return 0;
}