其实没啥的。
离散化后,每行每列选择一个。
但是可能会相交
每行或每列相邻两个点成为一小段。
小段按照行列左右部点
小段有交,连inf边,每个s-左,右-t,连1
最小割。
输出方案真的很麻烦。。。
代码难度>思维含量的网络流,,,
#include<bits/stdc++.h> #define reg register int #define il inline #define fi first #define se second #define mk(a,b) make_pair(a,b) #define numb (ch^'0') #define pb push_back #define solid const auto & #define enter cout<<endl #define pii pair<int,int> using namespace std; typedef long long ll; template<class T>il void rd(T &x){ char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);} template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');} template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');} template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar(' ');} namespace Modulo{ const int mod=998244353; int ad(int x,int y){return (x+y)>=mod?x+y-mod:x+y;} void inc(int &x,int y){x=ad(x,y);} int mul(int x,int y){return (ll)x*y%mod;} void inc2(int &x,int y){x=mul(x,y);} int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;} } //using namespace Modulo; namespace Miracle{ const int N=1005; const int inf=0x3f3f3f3f; int n; struct node{ int nxt,to; int w; }e[2*(N*N+N+N)]; int hd[2*N],cnt=1; void add(int x,int y,int w){ e[++cnt].nxt=hd[x]; e[cnt].to=y;e[cnt].w=w; hd[x]=cnt; e[++cnt].nxt=hd[y]; e[cnt].to=x;e[cnt].w=0; hd[y]=cnt; } int d[2*N]; int s,t; int dfs(int x,int flow){ if(x==t) return flow; int res=flow; for(reg i=hd[x];i&&res;i=e[i].nxt){ int y=e[i].to; if(d[y]==d[x]+1){ int k=dfs(y,min(res,e[i].w)); if(!k) d[y]=0; res-=k; e[i].w-=k; e[i^1].w+=k; } } return flow-res; } int q[2*N],l,r; bool bfs(){ l=1,r=0; memset(d,0,sizeof d); q[++r]=t; d[t]=t+1; while(l<=r){ int x=q[l++]; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(e[i^1].w&&!d[y]){ d[y]=d[x]-1; q[++r]=y; if(y==s) return true; } } } return false; } struct po{ int x,y; po(){} po(int xx,int yy){ x=xx;y=yy; } void op(){ ot(x);ot(y); } }p[N]; struct line{ int pos,l,r; }X[N],Y[N]; int cx,cy; int th[N],hc; int tl[N],lc; vector<int>hang[N],lie[N]; vector<int>ex[N],ey[N]; bool jiao(line a,line b){ if((b.l<=a.pos&&a.pos<=b.r)&&(a.l<=b.pos&&b.pos<=a.r)) return true; return false; } bool vis[2*N]; void fin(){ l=1,r=0; q[++r]=s; vis[s]=1; while(l<=r){ int x=q[l++]; // cout<<" fin "<<x<<endl; for(reg i=hd[x];i;i=e[i].nxt){ int y=e[i].to; if(!vis[y]&&e[i].w){ vis[y]=1; q[++r]=y; } } } // cout<<" visiv "<<endl; // prt(vis,s,t); } struct sol{ po a,b; }ax[N],ay[N]; int ansx,ansy; int main(){ rd(n); for(reg i=1;i<=n;++i){ rd(p[i].x);rd(p[i].y); tl[++lc]=p[i].x; th[++hc]=p[i].y; } sort(tl+1,tl+lc+1); lc=unique(tl+1,tl+lc+1)-tl-1; sort(th+1,th+hc+1); hc=unique(th+1,th+hc+1)-th-1; for(reg i=1;i<=n;++i){ int tx=lower_bound(tl+1,tl+lc+1,p[i].x)-tl; int ty=lower_bound(th+1,th+hc+1,p[i].y)-th; hang[ty].pb(p[i].x); lie[tx].pb(p[i].y); } for(reg i=1;i<=lc;++i) sort(lie[i].begin(),lie[i].end()); for(reg i=1;i<=hc;++i) sort(hang[i].begin(),hang[i].end()); for(reg i=1;i<=lc;++i){ if(!lie[i].size()) continue; int las=lie[i][0]; for(reg j=1;j<lie[i].size();++j){ int now=lie[i][j]; if(now-1>=las+1){ ++cx; X[cx].pos=tl[i]; X[cx].r=now-1; X[cx].l=las+1; ex[i].pb(cx); } las=now; } } for(reg i=1;i<=hc;++i){ if(!hang[i].size()) continue; int las=hang[i][0]; for(reg j=1;j<hang[i].size();++j){ int now=hang[i][j]; if(now-1>=las+1){ ++cy; Y[cy].pos=th[i]; Y[cy].r=now-1; Y[cy].l=las+1; ey[i].pb(cy); } las=now; } } s=0;t=cx+cy+1; for(reg i=1;i<=cx;++i){ add(s,i,1); for(reg j=1;j<=cy;++j){ if(jiao(X[i],Y[j])){ // cout<<" jiao "<<i<<" j "<<j<<endl; add(i,j+cx,inf); } } } for(reg i=1;i<=cy;++i){ add(i+cx,t,1); } while(bfs())while(dfs(s,inf)); fin(); // cout<<" cx "<<cx<<" cy "<<cy<<endl; for(reg i=1;i<=lc;++i){ if(!lie[i].size()) continue; int le=lie[i][0],ri; for(solid now:ex[i]){ if(vis[s]!=vis[now]){ ri=X[now].l-1; ++ansx; ax[ansx].a=po(X[now].pos,le); ax[ansx].b=po(X[now].pos,ri); le=X[now].r+1; } } ri=lie[i][lie[i].size()-1]; ++ansx; ax[ansx].a=po(tl[i],le); ax[ansx].b=po(tl[i],ri); } for(reg i=1;i<=hc;++i){ // cout<<" i "<<i<<" : "<<th[i]<<endl; if(!hang[i].size()) continue; int le=hang[i][0],ri; for(solid now:ey[i]){ if(vis[t]!=vis[now+cx]){ ri=Y[now].l-1; ++ansy; // cout<<" new "<<endl; ay[ansy].a=po(le,Y[now].pos); ay[ansy].b=po(ri,Y[now].pos); le=Y[now].r+1; } } ri=hang[i][hang[i].size()-1]; ++ansy; ay[ansy].a=po(le,th[i]); ay[ansy].b=po(ri,th[i]); } printf("%d ",ansy); for(reg i=1;i<=ansy;++i){ ay[i].a.op();ay[i].b.op();puts(""); } // puts(""); printf("%d ",ansx); for(reg i=1;i<=ansx;++i){ ax[i].a.op();ax[i].b.op();puts(""); } return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* */