【比賽】NOIP2018 旅行
阿新 • • 發佈:2019-01-01
發現 \(m\) 只有兩種取值,於是可做了
樹的直接貪心
圖的列舉環上的邊去掉,然後做樹的貪心,搜的時候剪一下枝吧
寫得有點亂
#include<bits/stdc++.h> #define ui unsigned int #define ll long long #define db double #define ld long double #define ull unsigned long long #define ft first #define sd second #define pb(a) push_back(a) #define mp(a,b) std::make_pair(a,b) #define REP(a,b,c) for(register int a=(b),a##end=(c);a<=a##end;++a) #define DEP(a,b,c) for(register int a=(b),a##end=(c);a>=a##end;--a) const int MAXN=5000+10; int n,m,e=1,key,beg[MAXN],nex[MAXN<<1],to[MAXN<<1],was[MAXN<<1],cnt,dfn[MAXN],ans[MAXN],vis[MAXN],arv[MAXN]; std::vector<int> V[MAXN]; std::pair<int,int> ext,from[MAXN]; struct Unique{ int fa[MAXN]; inline void init(int x) { REP(i,1,x)fa[i]=i; } inline int found(int x) { if(fa[x]!=x)fa[x]=found(fa[x]); return fa[x]; } inline int link(int x,int y,int val) { int u=found(x),v=found(y),res=0; if(u!=v)fa[u]=v,res=val; return res; } }; Unique U; template<typename T> inline void read(T &x) { T data=0,w=1; char ch=0; while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')w=-1,ch=getchar(); while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar(); x=data*w; } template<typename T> inline void write(T x,char ch='\0') { if(x<0)putchar('-'),x=-x; if(x>9)write(x/10); putchar(x%10+'0'); if(ch!='\0')putchar(ch); } template<typename T> inline bool chkmin(T &x,T y){return y<x?(x=y,true):false;} template<typename T> inline bool chkmax(T &x,T y){return y>x?(x=y,true):false;} template<typename T> inline T min(T x,T y){return x<y?x:y;} template<typename T> inline T max(T x,T y){return x>y?x:y;} inline void insert(int x,int y,int z) { to[++e]=y; nex[e]=beg[x]; beg[x]=e; was[e]=z; } inline void sortdfs(int x,int f) { if(arv[x])return ;arv[x]=1; for(register int i=beg[x];i;i=nex[i])V[x].pb(to[i]),sortdfs(to[i],x); std::sort(V[x].begin(),V[x].end()); } inline void initdfs(int x,int f) { for(register int i=beg[x];i;i=nex[i]) if(to[i]==f||!was[i])continue; else initdfs(to[i],x),from[to[i]]=mp(x,i); } inline bool dfs(int x,int f,int &fl) { dfn[++cnt]=x; if(dfn[cnt]<ans[cnt])chkmin(fl,0); if(fl&&dfn[cnt]>ans[cnt])return false; int lack=-1; for(register int i=beg[x];i;i=nex[i]) if(to[i]==f)continue; else if(!was[i])lack=to[i]; REP(i,0,V[x].size()-1) if(V[x][i]==lack||V[x][i]==f)continue; else if(!dfs(V[x][i],x,fl))return false; return true; } inline int LCA(int u,int v) { while(u)vis[u]=1,u=from[u].ft; while(v) if(vis[v])return v; else v=from[v].ft; } inline void solve(int x) { int fl; while(x!=key) { was[from[x].sd]=was[from[x].sd^1]=0; cnt=0;if(dfs(1,0,fl=1))memcpy(ans,dfn,sizeof(ans)); was[from[x].sd]=was[from[x].sd^1]=1; x=from[x].ft; } } int main() { freopen("travel.in","r",stdin); freopen("travel.out","w",stdout); read(n);read(m); U.init(n);int fl; REP(i,1,n)ans[i]=n+1; REP(i,1,m) { int u,v;read(u);read(v); if(U.link(u,v,1))insert(u,v,1),insert(v,u,1); else ext=mp(u,v); } if(m==n-1)sortdfs(1,0),dfs(1,0,fl=1),memcpy(ans,dfn,sizeof(ans)); else { initdfs(1,0); insert(ext.ft,ext.sd,0); insert(ext.sd,ext.ft,0); sortdfs(1,0); dfs(1,0,fl=1),memcpy(ans,dfn,sizeof(ans)); was[e]=was[e-1]=1; key=LCA(ext.ft,ext.sd); solve(ext.ft),solve(ext.sd); } REP(i,1,n)write(ans[i],i==iend?'\n':' '); return 0; }