#include<bits/stdc++.h> #define FILE "read" #define INF 1000000000 using namespace std; const int MAXN=(int)5010; struct node{int y,next,v,w,rel;}e[200000]; int n,len,S,T,TT,ans,Link[MAXN],vis[MAXN],dis[MAXN],q[MAXN],lastnode[MAXN],lastedge[MAXN],flow[MAXN]; pair<int,int> a[MAXN]; namespace INIT{ char buf[1<<15],*fs,*ft; inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;} inline int read(){ int x=0,f=1; char ch=getc(); while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getc();} while(isdigit(ch)) {x=x*10+ch-'0'; ch=getc();} return x*f; } }using namespace INIT; void insert(int x,int y,int v,int w){ e[++len].next=Link[x];Link[x]=len;e[len].y=y;e[len].v=v;e[len].w=-w;e[len].rel=len+1; e[++len].next=Link[y];Link[y]=len;e[len].y=x;e[len].v=0;e[len].w=w;e[len].rel=len-1; } bool spfa(){ memset(vis,0,sizeof(vis)); memset(dis,10,sizeof(dis)); int head=0,tail=1,oo=dis[0]; q[1]=S; dis[S]=0; vis[S]=1; flow[S]=INF; while(head!=tail){ int x=q[++head]; vis[x]=0; if(head==5000) head=0; for(int i=Link[x];i;i=e[i].next){ if(e[i].v&&e[i].w+dis[x]<dis[e[i].y]){ dis[e[i].y]=e[i].w+dis[x]; flow[e[i].y]=min(e[i].v,flow[x]); if(!vis[e[i].y]){ vis[e[i].y]=1; q[++tail]=e[i].y; if(tail==5000) tail=0; } lastnode[e[i].y]=x; lastedge[e[i].y]=i; } } } if(dis[T]==oo) return 0; ans+=flow[T]*(-dis[T]); for(int i=T;i!=S;i=lastnode[i]){ e[lastedge[i]].v-=flow[T]; e[e[lastedge[i]].rel].v+=flow[T]; } return 1; } void solve(){ while(spfa()); printf("%d\n",ans); } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); n=read(); S=n*2+1; TT=S+1; T=TT+1; for(int i=1;i<=n;++i){ a[i].first=read(); a[i].second=read(); insert(0,i,2,0); insert(i,i+n,1,1); insert(i,i+n,1,0); insert(i+n,TT,2,0); } sort(a+1,a+n+1); for(int i=1;i<=n;++i){ int maxx=INF; for(int j=i+1;j<=n;++j) if(a[j].second>=a[i].second&&a[j].second<maxx){ insert(i+n,j,2,0); maxx=a[j].second; } } insert(S,0,2,0); insert(TT,T,2,0); solve(); return 0; }
|