51nod 1273 旅行计划(思惟题)

  一开始看到这题真的有点懵逼...一直在想着套算法,结果题解除了sort和dfs其余什么都没用到ios

  显然每次到达的必定都是叶子,先从根节点dfs一遍,按深度对叶子降序排序,按这个顺序向根节点dfs,路径上没有被以前的叶子遍历过的点就是到达这个叶子时未通过的点的个数,因而咱们跑出全部叶子未通过点的个数再排序一次输出就好了
算法

#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath> #include<map>
#define ll long long 
using namespace std; const int maxn=500010,inf=1e9; struct tjm{int too,pre;}e[maxn]; struct poi{int w,pos;}a[maxn],b[maxn]; int n,x,tot,cnt,root,t; int last[maxn]; bool v[maxn]; void read(int &k) { int f=1;k=0;char c=getchar(); while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar(); k*=f; } inline bool cmp(poi a,poi b){return a.w==b.w?a.pos<b.pos:a.w>b.w;} inline void add(int x,int y){e[++tot].too=y;e[tot].pre=last[x];last[x]=tot;} inline void dfs(int x,int dep,int fa) { bool flag=0; for(int i=last[x];i;i=e[i].pre) if(e[i].too!=fa)dfs(e[i].too,dep+1,x),flag=1; if((!flag)&&x!=root)a[++cnt].pos=x,a[cnt].w=dep; } inline bool dfs2(int x,int fa) { if(x==root||v[x])return 1; for(int i=last[x];i;i=e[i].pre) if(e[i].too!=fa)if(dfs2(e[i].too,x))return t++,v[x]=1,1; return 0; } int main() { read(n);read(root); for(int i=1;i<n;i++)read(x),add(x,i),add(i,x); dfs(root,0,-1);sort(a+1,a+1+cnt,cmp); for(int i=1;i<=cnt;i++) { t=0;b[i].pos=a[i].pos; dfs2(a[i].pos,-1); b[i].w=t; } sort(b+1,b+1+cnt,cmp); printf("%d\n",root);for(int i=1;i<=cnt;i++)printf("%d\n",b[i].pos); return 0; }
View Code

先分析,再作题!ide

相关文章
相关标签/搜索