这样对于每个i-i+1都可以得到一条合法线,那么半平面交就OK
代码
T1
//Copyright(c)2016 liuchenrui #include<cstdio> #include<algorithm> #include<cstring> #define inf 1000000000 using namespace std; inline void splay(int &v){ v=0;char c=0;int p=1; while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();} while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();} v*=p; } int a[255][255]; struct Edge{ int to,next,flow; }edge[1000010]; int first[600],size; int deep[600],dl[600]; void addedge(int x,int y,int z){ size++; edge[size].to=y; edge[size].next=first[x]; first[x]=size; edge[size].flow=z; } int dfs(int now,int flow,int aim){ if(now==aim)return flow; int F=0; for(int u=first[now];u&&flow;u=edge[u].next){ if(deep[edge[u].to]==deep[now]+1&&edge[u].flow){ int tmp=dfs(edge[u].to,min(flow,edge[u].flow),aim); F+=tmp;edge[u].flow-=tmp;edge[u^1].flow+=tmp;flow-=tmp; } } if(!F)deep[now]=-5; return F; } bool bfs(int S,int T){ memset(deep,0,sizeof(deep)); dl[1]=S;deep[S]=1; int head=0,tail=1; while(head!=tail){ int v=dl[++head]; for(int u=first[v];u;u=edge[u].next){ if(!deep[edge[u].to]&&edge[u].flow){ dl[++tail]=edge[u].to; deep[edge[u].to]=deep[v]+1; } } } return deep[T]; } int maxflow(int S,int T){ int ret=0; while(bfs(S,T)){ ret+=dfs(S,inf,T); } return ret; } int n,m,k; int check(int mid){ memset(first,0,sizeof first);size=1; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i][j]<=mid){ addedge(i,j+250,1); addedge(j+250,i,0); } } } for(int i=1;i<=n;i++){ addedge(0,i,1); addedge(i,0,0); } for(int j=1;j<=m;j++){ addedge(j+250,550,1); addedge(550,j+250,0); } int tmp=maxflow(0,550); return tmp; } int main(){ freopen("matrix.in","r",stdin); freopen("matrix.out","w",stdout); splay(n),splay(m),splay(k); k=n-k+1; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ splay(a[i][j]); } } int l=0,r=1000000009; while(l!=r){ int mid=l+r>>1; if(check(mid)<k)l=mid+1; else r=mid; } printf("%d\n",l); }
//Copyright(c)2016 liuchenrui #include<cstdio> #include<ctime> #include<iostream> #include<algorithm> #include<cstring> using namespace std; inline void splay(int &v){ v=0;char c=0;int p=1; while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();} while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();} v*=p; } struct SCOI2015{ int l,r; int id; }s[200010],e[200010]; int Ans[200010]; bool comp(const SCOI2015 &a,const SCOI2015 &b){ return a.l<b.l; } bool in(int now,int l,int r){ if(now==1000000001)return false; if(l<=r){ if(now>=l && now<=r)return true; else return false; } else{ if(now>=l || now<=r)return true; else return false; } } int p[400010]; int t[400010][21]; int A[400010]; int n,m; int main(){ freopen("flag.in","r",stdin); freopen("flag.out","w",stdout); splay(n),splay(m); for(int i=1;i<=n;i++){ splay(e[i].l),splay(e[i].r); e[i].id=i; } sort(e+1,e+n+1,comp); for(int i=1;i<=n;i++){ s[i].l=e[i].l,s[i].r=e[i].r; s[i].id=i; } sort(s+1,s+n+1,comp); for(int i=1;i<=n;i++){ p[i]=p[i+n]=s[i].id; } p[n+n+1]=n+1; s[n+1].l=1000000001,s[n+1].r=1000000001; int now=p[1]; for(int i=1;i<=n<<1;i++){ while(in(s[p[now]].l,s[p[i]].l,s[p[i]].r)&&now!=i+n){ now++; } t[i][0]=now-1; } for(int k=1;k<=20;k++){ for(int i=1;i<=n<<1;i++){ t[i][k]=t[t[i][k-1]][k-1]; } } for(int i=1;i<=n;i++){ int aim=i+n,now=i,ans=1; for(int j=20;j>=0;j--){ if(t[now][j]<aim){ now=t[now][j]; ans+=(1<<j); } } Ans[s[i].id]=ans; } for(int i=1;i<=n;i++){ //printf("%d ",Ans[i]); A[e[i].id]=Ans[i]; } for(int i=1;i<=n;i++){ printf("%d ",A[i]); } }T3没调出来QAQ