UOJ496 新年的新航线(构造)
考虑多边形最外侧的三角形,可以发现与外侧的点相邻的两条边中必定恰好删除一条。
所以,我们把两条都删掉,然后在三角形内侧的边上打一个标记,表示要恢复一条边。
接下来的处理三角形需要考虑标记,不妨设这个三角形为 $(u,w,v)$($w$ 为外侧点),分类讨论:
- $(u,w)$ 与 $(w,v)$ 都有标记:把标记点都连到 $w$,再把 $w$ 标记到 $(u,,v)$ 上,这样 $w$ 的度为3;
- $(u,w)$ 与 $(w,v)$ 中有一个有标记:设 $(u,w)$ 有标记,则把标记点和 $w$ 都连到 $u$ 上;
- 都没有标记:把 $w$ 标记到 $(u,v)$ 上。
最后删到剩4个点时暴力搜一下即可。
复杂度 $O(n)$。
#include<cstdio> #define For(i,A,B) for(i=(A);i<=(B);++i) const int N=500050; char rB[1<<21],*rS,*rT,wB[(1<<21)+50]; int wp=-1; inline char gc(){return rS==rT&&(rT=(rS=rB)+fread(rB,1,1<<21,stdin),rS==rT)?EOF:*rS++;} inline void flush(){fwrite(wB,1,wp+1,stdout);wp=-1;} inline void pc(char c){if(wp>(1<<21))flush();wB[++wp]=c;} inline int rd(){ char c=gc(); while(c<48||c>57)c=gc(); int x=c&15; for(c=gc();c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c&15); return x; } short buf[15]; inline void wt(int x){ if(wp>(1<<21))flush(); short l=-1; while(x>9){ buf[++l]=x%10; x/=10; } wB[++wp]=x|48; while(l>=0)wB[++wp]=buf[l--]|48; } int G[N],to[N<<2],nex[N<<2],sz=0,d[N],lst[N],nxt[N],val[N],st[N],sl=-1,id[N],p[4],a[5],b[5],D[4]; bool del[N],used[5],chc[4]; inline void adde(int u,int v){ to[++sz]=v;nex[sz]=G[u];G[u]=sz; to[++sz]=u;nex[sz]=G[v];G[v]=sz; } bool dfs2(int h){ if(h==4)return D[0]!=2&&D[1]!=2&&D[2]!=2&&D[3]!=2; if(!val[p[h]])return dfs2(h+1); ++D[h];chc[h]=0; if(dfs2(h+1))return 1; --D[h];++D[h+1&3];chc[h]=1; if(dfs2(h+1))return 1; --D[h+1&3]; return 0; } bool dfs1(int h,int m){ if(!m)return dfs2(0); if(h==5)return 0; ++D[a[h]];++D[b[h]];used[h]=1; if(dfs1(h+1,m-1))return 1; --D[a[h]];--D[b[h]];used[h]=0; if(dfs1(h+1,m))return 1; return 0; } int main(){ int n=rd(),i,j,u,v,w,cnt=0; if(n==3){ puts("-1"); return 0; } For(i,4,n){ u=rd();v=rd(); adde(u,v); ++d[u];++d[v]; } For(i,1,n){ adde(lst[i]=i==1?n:i-1,i);nxt[i]=i==n?1:i+1; if(!d[i])st[++sl]=i; } For(i,5,n){ u=lst[w=st[sl--]];v=nxt[w]; if(val[u])if(val[w]){ wt(w);pc(' ');wt(val[u]);pc('\n'); wt(w);pc(' ');wt(val[w]);pc('\n'); val[u]=w; }else{ wt(u);pc(' ');wt(w);pc('\n'); wt(u);pc(' ');wt(val[u]);pc('\n'); val[u]=0; }else if(val[w]){ wt(v);pc(' ');wt(w);pc('\n'); wt(v);pc(' ');wt(val[w]);pc('\n'); }else val[u]=w; del[w]=1; lst[nxt[u]=v]=u; if(!--d[u])st[++sl]=u; if(!--d[v])st[++sl]=v; } For(i,1,n)if(!del[i])p[id[i]=cnt++]=i; cnt=0; For(i,0,3) for(j=G[p[i]];j;j=nex[j])if(!del[v=to[j]]&&i<id[v]){a[cnt]=i;b[cnt++]=id[v];} dfs1(0,3); For(i,0,4)if(used[i]){wt(p[a[i]]);pc(' ');wt(p[b[i]]);pc('\n');} For(i,0,3)if(val[p[i]]){ wt(val[p[i]]);pc(' '); wt(chc[i]?p[i+1&3]:p[i]); pc('\n'); } flush(); return 0; }