[HDU 4118]Holiday's Accommodation[图论][非递归dfs]
来源:互联网 发布:广州谷得知乎 编辑:程序博客网 时间:2024/06/06 17:03
题意:
有一棵树, 节点表示城市, 每个城市有一个人. 人们要旅行到其他城市. 相当于一个置换. 求总的路程最大值.
思路:
ans = Σ (每条路长 l )*(经过这条路的最大次数 f )
f = 2 * 这条边左边节点数和右边节点数最小值k. (这样左边的每一个点一定能够对应右边的某个点)
这个k可以dfs 求得.
但是直接dfs 会爆栈...
需要将其改为非递归...
#include <stdio.h>#include <cstring>#include <stack>using namespace std;struct gtype{ int y,d,next;} g[200010];int first[100100],tot,a[100100],tt,x,y,d,n;bool v[100100];inline int min(int a,int b){ if (a<b) return a; else return b;}void add(int x,int y,int d){ tot++; g[tot].d=d; g[tot].y=y; g[tot].next=first[x]; first[x]=tot; tot++; g[tot].d=d; g[tot].y=x; g[tot].next=first[y]; first[y]=tot;}void dfs(int p){ stack <int> stk; int t=first[p]; stk.push(p); v[p]=true; while (1) { if (t==-1)//该点的所有边已经遍历完 { int y = stk.top(); stk.pop(); if (stk.empty()) break;//dfs结束 a[stk.top()]+=a[y]; //该点的子树节点数加到其父节点上, 表示该节点相对其父节点已经处理完 } int x = stk.top();///每次从栈顶取出元素!! t = first[x]; while (t!=-1) { if (!v[g[t].y]) { v[g[t].y]=true; stk.push(g[t].y); break;///一旦前进,便跳出,继续判断或者取栈顶元素.否则就相当于bfs了!!! } t=g[t].next; } }}int main(){ scanf("%d",&tt); for (int cas=1; cas<=tt; cas++) { tot=0; memset(g,0,sizeof(g)); memset(first,-1,sizeof(first)); scanf("%d",&n); for (int i=1; i<n; i++) { scanf("%d%d%d",&x,&y,&d); add(x,y,d); } for (int i=1; i<=n; i++) a[i]=1;//记录节点的儿子数,初始化时已经算上了自己 memset(v,0,sizeof(v)); dfs(1);//填a数组 __int64 ans=0; for (int i=1; i<=2*(n-1); i+=2) {//遍历池子,即遍历每一条边 x=g[i].y; y=g[i+1].y; d=min(a[x],a[y]); ans+=min(d,n-d)*2*g[i].d; } printf("Case #%d: %I64d\n",cas,ans); } return 0;}
自己敲一遍. 尤其要感受一下是如何改非递归的!
#include <cstdio>#include <cstring>#include <algorithm>#include <stack>using namespace std;const int MAXN = 100005;typedef long long ll;struct edge{ int v, w, next;}g[MAXN<<1];int head[MAXN],num;int a[MAXN];bool vis[MAXN];int n;stack<int> s;void add(int u, int v, int w){ g[++num].v = v; g[num].w = w; g[num].next = head[u]; head[u] = num; g[++num].v = u; g[num].w = w; g[num].next = head[v]; head[v] = num;}void dfs(int k){ memset(vis,false,sizeof(vis)); vis[k] = true; s.push(k); int t = head[k]; while(true) { if(!t) { int u = s.top(); s.pop();//deal with tmp node if(s.empty()) break; a[s.top()] += a[u]; } int u = s.top(); t = head[u]; while(t) { if(!vis[g[t].v]) { vis[g[t].v] = true; s.push(g[t].v); break; } t = g[t].next; } }}int main(){ int T,cas = 0; scanf("%d",&T); while(T--) { num = 0; memset(head,0,sizeof(head)); memset(g,0,sizeof(g)); scanf("%d",&n); for(int i=1;i<n;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); } for(int i=1;i<=n;i++) a[i] = 1; dfs(1); ll ans = 0; for(int i=1;i<2*(n-1);i+=2) { int u = g[i].v; int v = g[i+1].v; int k = min(a[u],a[v]);//a记录子树大小,较小的那个是"一边的节点数" ans += 2ll*min(k,n-k)*g[i].w;//n-k是对面的个数 } printf("Case #%d: %I64d\n",++cas,ans); }}
/* 自律 专注 保持活力 */
- [HDU 4118]Holiday's Accommodation[图论][非递归dfs]
- hdu Holiday's Accommodation dfs
- HDU 4118 Holiday's Accommodation
- HDU-4118-Holiday's Accommodation
- hdu 4118 Holiday's Accommodation
- HDU - 4118 Holiday's Accommodation
- hdu Holiday's Accommodation
- Holiday's Accommodation HDU
- 【树形DP】 HDU 4118 Holiday's Accommodation
- hdu 4118 Holiday's Accommodation 树上统计
- hdu 4118 Holiday's Accommodation 树形dp
- hdu 4118 Holiday's Accommodation 树形dp
- HDOJ 4118 Holiday's Accommodation
- HDU4118:Holiday's Accommodation(思维 & dfs)
- hdu 4118 Holiday's Accommodation 2011 Asia ChengDu Regional Contest
- HDU 4118--Holiday's Accommodation(树形dp)
- HDU 4118 Holiday's Accommodation(树形DP)
- HDU 4118 Holiday's Accommodation 贪心(树的重心)
- Windows下安装Django
- 单调队列简述
- 针对VC版本及相关库的升级后程序无法运行问题举例说明
- Clib -- List
- Linux高性能集群 - 软件体系结构
- [HDU 4118]Holiday's Accommodation[图论][非递归dfs]
- 华为上机题
- main.cpp first defined here 解决
- Linux高性能集群 - 资源管理和系统管理
- A*算法入门
- 一个算法题:10个队分成3组,问有多少种分法
- 排序算法小结
- paip. 'QObject::QObject(const QObject&)' is private问题的解决.
- paip.c++ static 变量的定义以及使用...