标签:它的 ios 规划 line idt back space opera while
定理 答案不会超过定向前由已经定向的边组成的最长路的长度加1。
我也不会证明qwq。
假设当前由已经定向的边组成的最长路的长度为$L$,那么只用判定答案是否能是$L$。
考虑对于一个未定向的边$(u, v)$($u$的深度更浅)我们给它定向,不妨设它的方向是指向父节点。
那么在$v$的子树中方向向$v$的子树内的有向路径对当前的点没有影响。
因此我们只用考虑求出每个点满足条件的时候,以它作为起点的时候,方向向子树内的最长有向路径的最小长度,以及当它作为终点的时候,子树内方向向父节点的最长有向路径的最小长度。
考虑怎么计算它们。
首先已经被定向的边无力改变。
对于还未定向的边连接的子树,考虑将它们按照某一种权值排序,然后枚举这种权值的最大值,再记录另一种权值的后缀最大值,判断是否合法,合法就更新上面两个值,如果不合法就改成$\infty$。再对另外一种权值做一遍。
时间复杂度$O(n\log n)$
1 /** 2 * UVa Live 3 * Problem#3683 4 * Accepted 5 * Time: 0ms 6 */ 7 #include <algorithm> 8 #include <iostream> 9 #include <cstdlib> 10 #include <cstdio> 11 #include <vector> 12 using namespace std; 13 typedef bool boolean; 14 15 const signed int inf = (signed) (~0u >> 3); 16 17 const int N = 205; 18 19 typedef pair<int, int> pii; 20 21 template <typename T> 22 void pfill(T* pst, const T* ped, T val) { 23 for ( ; pst != ped; *(pst++) = val); 24 } 25 26 typedef class Edge { 27 public: 28 int ed, nx, rev; // rev = 0: undirected, rev = 1: positive order, rev = -1: reverse order 29 30 Edge(int ed = 0, int nx = 0, int rev = 0):ed(ed), nx(nx), rev(rev) { } 31 }Edge; 32 33 typedef class MapManager { 34 public: 35 int h[N]; 36 vector<Edge> es; 37 38 void init(int n) { 39 pfill(h + 1, h + n + 1, -1); 40 es.clear(); 41 } 42 43 void addEdge(int u, int v, int rev) { 44 es.push_back(Edge(v, h[u], rev)); 45 h[u] = (signed) es.size() - 1; 46 } 47 48 Edge& operator [] (int p) { 49 return es[p]; 50 } 51 }MapManager; 52 53 int n, m; 54 MapManager g; 55 boolean vis[N]; 56 int fu[N], fd[N], d[N]; 57 58 inline boolean init() { 59 static int u, v; 60 static char buf[12], *c; 61 62 boolean aflag = false; 63 g.init(N - 1); 64 while (~scanf("%d", &u) && u) { 65 aflag = true; 66 n = max(n, u); 67 while (~scanf("%s", buf) && buf[0] != ‘0‘) { 68 for (v = 0, c = buf; *c >= ‘0‘ && *c <= ‘9‘; v = v * 10 + *c - ‘0‘, c++); 69 n = max(n, v); 70 if (*c == ‘d‘) { 71 g.addEdge(u, v, 1); 72 g.addEdge(v, u, -1); 73 } else if (*c == ‘u‘) { 74 g.addEdge(u, v, -1); 75 g.addEdge(v, u, 1); 76 } else { 77 g.addEdge(u, v, 0); 78 g.addEdge(v, u, 0); 79 } 80 81 // cerr << u << " " << v << ‘\n‘; 82 } 83 } 84 85 return aflag; 86 } 87 88 int dfs(int p, int fa) { 89 if (vis[p]) 90 return d[p]; 91 vis[p] = true, d[p] = 1; 92 for (int i = g.h[p], e; ~i; i = g[i].nx) { 93 if (((e = g[i].ed) ^ fa) && g[i].rev == 1) 94 d[p] = max(d[p], dfs(e, p) + 1); 95 } 96 return d[p]; 97 } 98 99 int res; 100 void dp_main(int p, int fa) { 101 static pii tmp[N]; 102 103 int max_up = 0, max_do = 0, tp = 0; 104 for (int i = g.h[p], e; ~i; i = g[i].nx) { 105 if ((e = g[i].ed) == fa) 106 continue; 107 dp_main(e, p); 108 109 if (g[i].rev == 1) 110 max_do = max(max_do, fd[e]); 111 if (g[i].rev == -1) 112 max_up = max(max_up, fu[e]); 113 } 114 115 for (int i = g.h[p], e; ~i; i = g[i].nx) { 116 if ((e = g[i].ed) == fa || g[i].rev) 117 continue; 118 tmp[++tp] = pii(fd[e], fu[e]); 119 } 120 121 fd[p] = fu[p] = inf; 122 if (!tp) { 123 if (max_do + max_up + 1 <= res) { 124 fd[p] = max_do + 1; 125 fu[p] = max_up + 1; 126 } 127 return ; 128 } 129 130 tmp[++tp] = pii(0, 0); 131 sort(tmp + 1, tmp + tp + 1, [&] (const pii& a, const pii& b) { return a.first < b.first; }); 132 133 int mx = 0; 134 for (int i = tp; i; i--) { 135 if (max(tmp[i].first, max_do) + max(mx, max_up) + 1 <= res) 136 fd[p] = max(tmp[i].first, max_do) + 1; 137 mx = max(mx, tmp[i].second); 138 } 139 140 sort(tmp + 1, tmp + tp + 1, [&] (const pii& a, const pii& b) { return a.second < b.second; }); 141 142 mx = 0; 143 for (int i = tp; i; i--) { 144 if (max(tmp[i].second, max_up) + max(mx, max_do) + 1 <= res) 145 fu[p] = max(tmp[i].second, max_up) + 1; 146 mx = max(mx, tmp[i].first); 147 } 148 // cerr << p << " " << fu[p] << " " << fd[p] << ‘\n‘; 149 } 150 151 inline void solve() { 152 res = 0; 153 pfill(vis + 1, vis + n + 1, false); 154 for (int i = 1; i <= n; i++) { 155 res = max(res, dfs(i, 0)); 156 if (res == 4) 157 cerr << i << ‘\n‘; 158 } 159 // cerr << res << ‘\n‘; 160 dp_main(1, 0); 161 printf("%d\n", res + (fu[1] + fd[1] - 1 > res)); 162 } 163 164 int main() { 165 while (init()) 166 solve(); 167 return 0; 168 }
UVa Live 3683 A Scheduling Problem - 动态规划
标签:它的 ios 规划 line idt back space opera while
原文地址:https://www.cnblogs.com/yyf0309/p/9917998.html