码迷,mamicode.com
首页 > 其他好文 > 详细

UVa Live 3683 A Scheduling Problem - 动态规划

时间:2018-11-06 21:24:01      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:它的   ios   规划   line   idt   back   space   opera   while   

题目传送门

  传送门

题目大意

  给定一个树,其中有一些边已经定向,要求为剩下的边定向使得最长路最短。

定理 答案不会超过定向前由已经定向的边组成的最长路的长度加1。

  我也不会证明qwq。

  假设当前由已经定向的边组成的最长路的长度为$L$,那么只用判定答案是否能是$L$。

  考虑对于一个未定向的边$(u, v)$($u$的深度更浅)我们给它定向,不妨设它的方向是指向父节点。

  那么在$v$的子树中方向向$v$的子树内的有向路径对当前的点没有影响。

  因此我们只用考虑求出每个点满足条件的时候,以它作为起点的时候,方向向子树内的最长有向路径的最小长度,以及当它作为终点的时候,子树内方向向父节点的最长有向路径的最小长度。

  考虑怎么计算它们。

  首先已经被定向的边无力改变。

  对于还未定向的边连接的子树,考虑将它们按照某一种权值排序,然后枚举这种权值的最大值,再记录另一种权值的后缀最大值,判断是否合法,合法就更新上面两个值,如果不合法就改成$\infty$。再对另外一种权值做一遍。

  时间复杂度$O(n\log n)$

Code

  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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!