POJ 3107 - Godfather
2014-05-01 01:29
363 查看
本题与POJ 1655的区别是要把所有重心的点按顺序输出出来。
5/3更新 求树的重心模板:
// poj3107 Godfather #include <cstdio> #include <cstring> #define NDEBUG #define MAXN 50005 using namespace std; int N; int edgefw[MAXN*2], edge[MAXN*2], head[MAXN], eptr; #define EI(j, k) ({ \ edge[eptr] = k, edgefw[eptr] = head[j]; \ head[j] = eptr++; \ }) int dp[MAXN], dp2[MAXN]; char vis[MAXN]; void dfs(int i) { vis[i] = 1; int p, maxk = 0, sumn = 1; for(p = head[i]; p>=0; p = edgefw[p]) { int t = edge[p]; if (!vis[t]) { if (!dp2[t]) dfs(t); sumn += dp2[t]; if (maxk < dp2[t]) maxk = dp2[t]; } } if (sumn != N && N - sumn > maxk) maxk = N - sumn; dp[i] = maxk, dp2[i] = sumn; } int main(void) { #ifndef NDEBUG freopen("poj3107.in", "r", stdin); #endif // NDEBUG scanf("%d", &N); memset(head, -1, sizeof(int) * N), eptr = 0; int i, j, root; root = 0; for(i=1; i<N; ++i) { int k; scanf("%d%d", &j, &k); --j,--k; EI(j, k), EI(k, j); if (root == k) root = j; } dfs(root); j = 0; for(i = 1; i < N; ++i) if (dp[i] < dp[j]) j = i; root = 0; for(i = 0; i < N; ++i) if (dp[i] == dp[j]) { printf("%d", ++i); break; } for(; i<N; ++i) if (dp[i] == dp[j]) printf(" %d", i+1); putchar('\n'); return 0; }
3107 | Accepted | 4104K | 532MS | G++ | 1249B | 2014-05-01 01:22:57 |
#include <cstdio> #include <cstring> using namespace std; #define FOR(p,i,s,t) for(__typeof(p) i=s; i<t; ++i) #define REP(t,i,n) FOR(t,i,0,n) #define ECH(it, A) for (__typeof(A.begin()) it=A.begin(); it != A.end(); ++it) #define RST(x,y) memset(x, y, sizeof(x)) #define RST0(x) RST(x,0) typedef int Vt, Lt; const __typeof(Vt) MAXV = 50005; #define MAXE ((MAXV<<1) - 2) Vt Vefw[MAXE], Veh[MAXV], eptr = 0; struct Vedge { Vt t; Lt l; Vedge() {} Vedge(Vt _t): t(_t), l(1) {} Vedge(Vt _t, Lt _l): t(_t), l(_l) {} void attach(Vt s) { extern Vedge Vs[]; memcpy(Vs + eptr, this, sizeof(Vedge)); Vefw[eptr] = Veh[s]; Veh[s] = ++eptr; } }; #define addedge(s,t,l) ({Vedge e(t,l); e.attach(s);}) Vedge Vs[MAXE]; Vt gcoref_tot; char gc_8[MAXV]; Vt gc_maxk[MAXV], gc_sumn[MAXV]; int gc_root; void gcoref(Vt i) { char _gc8; if (!(_gc8 = gc_8[i])) gc_8[i] = -1; // 遍历去环 Vt sumn = 1, maxk = 0; for(Vt e = Veh[i]; e; e = Vefw[e]) { Vt t = Vs[--e].t; if (!gc_8[t]) { gcoref(t); sumn += gc_sumn[t]; if (maxk < gc_sumn[t]) maxk = gc_sumn[t]; } } gc_8[i] = _gc8; // gc_8还有其他用途 if (gcoref_tot - sumn > maxk) maxk = gcoref_tot - sumn; gc_sumn[i] = sumn, gc_maxk[i] = maxk; if (gc_maxk[gc_root] > maxk) gc_root = i; } inline Vt gcore(Vt root) { gc_maxk[gc_root = root] = gcoref_tot; gcoref(root); return gc_root; } int N; // 本模板使用方式: gcoref_tot = 实际节点数 // gc_8 != 0, 该节点被剪掉(忽略),可以用来存储其他信息 // addedge加边(注意针对 无根树 要加双向),gcore返回重心节点 // gc_maxk里面存储所有节点的最大真子树的节点数. int main(void) { // freopen("poj3107.txt", "r", stdin); scanf("%d", &N); Vt root = 0; REP(int, i, N-1) { Lt l; Vt s,t; scanf("%d%d", &s, &t); --s, --t; addedge(s,t,1), addedge(t,s,1); if (root == t) root = s; } gcoref_tot = N; root = gcore(root); Vt i; for(i = 0; i < N; ++i) if (gc_maxk[i] == gc_maxk[root]) { printf("%d", ++i); break; } for(; i<N; ++i) if (gc_maxk[i] == gc_maxk[root]) printf(" %d", i+1); putchar('\n'); return 0; }
相关文章推荐
- doubango介绍
- Beego源码分析
- A* algorithm Sketch
- Mongoose在创建Model时对Collection的命名策略
- POJ 2007 Scrambled Polygon
- sortAlgorithms
- sortAlgorithms
- Google guava
- mac安装Genymotion模拟器教程(mac机如何在模拟器上玩googleplay游戏)
- GoF著作中未提到的设计模式(6):Specification
- GoF著作中未提到的设计模式(7):Publish-Subscribe
- GoF著作中未提到的设计模式(1): Archetype
- ACM-ICPC 4836 Gomoku
- Google SPDY
- 解决在ubuntu系统中安装Chrome失败的问题
- 用线框模式绘制多边形 glPolygonMode
- django 学习笔记(四)
- Google Breakpad: 实战crash .
- 电脑下载google play store的apk
- 构建一个Mongo分片集群