# UVA 1380 A Scheduling Problem

$LRJ$紫书例题$9-26$

$HIT:$ 题目额外给了一个结论 假设已经确定方向的边所能得到的最长链为$k$ 最后的最长链一定$k$ 或$k + 1$

$f[x][y]$代表 到达该根节点$x$的向上的最长链最小值为$y$时向下的最长链最小值为多少

$up[x]$ $down[x]$分别代表该根节点向上/下的最长链的最小值

  1 #include <bits/stdc++.h>
2 using namespace std;
3 const int N = 210, E = N << 1;
4 int firste[N], nexte[E], v[E], w[E];
5 int n, e, ans;
6 void build(int x, int y, int z)
7 {
8     nexte[++e] = firste[x];
9     firste[x] = e;
10     v[e] = y;
11     w[e] = z;
12 }
13 void init(int uu)
14 {
15     int vv;
16     char ch;
17     n = 0;
18     e = 1;
19     memset(firste, 0, sizeof firste);
20     ans = 0;
21     do
22     {
23         n = max(n, uu);
24         while(scanf("%d%c", &vv, &ch), vv)
25         {
26             n = max(n, vv);
27             if(ch == 'd')
28             {
29                 build(uu, vv, 1);
30                 build(vv, uu, 0);
31             }
32             else if(ch == 'u')
33             {
34                 build(uu, vv, 0);
35                 build(vv, uu, 1);
36             }
37             else
38             {
39                 build(uu, vv, 0);
40                 build(vv, uu, 0);
41             }
42         }
43     }while(scanf("%d", &uu), uu);
44 }
45 void dfs0(int u, int fa, int dist)
46 {
47     ans = max(ans, dist);
48     for(int p = firste[u]; p; p = nexte[p])
49         if(w[p] && v[p] != fa)
50             dfs0(v[p], u, dist + 1);
51 }
52 int f[N][N], up[N], down[N];
53 bool dfs(int u, int fa)
54 {
55     for(int p = firste[u]; p; p = nexte[p])
56         if(v[p] != fa)
57         {
58             if(!dfs(v[p], u))
59                 return 0;
60             if(w[p])
61             {
62                 for(int i = 0; i <= min(down[v[p]], ans); ++i)
63                     f[u][i] = ans + 1;
64             }
65             else if(w[p ^ 1])
66             {
67                 for(int i = 0; i <= ans; ++i)
68                     f[u][i] = max(f[u][i], up[v[p]] + 1);
69             }
70             else
71             {
72                 for(int i = 0; i <= down[v[p]]; ++i)
73                     f[u][i] = max(f[u][i], up[v[p]] + 1);
74             }
75         }
76     bool re = 0;
77     for(int i = 0; i <= ans; ++i)
78         if(f[u][i] + i <= ans)
79         {
80             re = 1;
81             down[u] = min(down[u], i);
82             up[u] = min(up[u], f[u][i]);
83         }
84     return re;
85 }
86 int main()
87 {
88     int tmp;
89     while(scanf("%d", &tmp), tmp)
90     {
91         init(tmp);
92         for(int i = 1; i <= n; ++i)
93                 dfs0(i, i, 0);
94         memset(f, 0, sizeof f);
95         memset(down, 0x3f, sizeof down);
96         memset(up, 0x3f, sizeof up);
97         if(dfs(1, 1))
98             printf("%d\n", ans + 1);
99         else
100             printf("%d\n", ans + 2);
101     }
102     return 0;
103 }

posted @ 2016-12-07 21:08 sagitta 阅读(...) 评论(...) 编辑 收藏