您的位置:首页 > 其它

[bzoj1023][SHOI2008]cactus 仙人掌图 (动态规划)

2015-03-28 11:54 411 查看

Description

如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人图(cactus)。所谓简单回路就是指在图上不重复经过任何一个顶点的回路。

1 /**************************************************************
2 Problem: 1023
3 User: AsmDef
4 Language: C++
5 Result: Accepted
6 Time:408 ms
7 Memory:8612 kb
8 ****************************************************************/
9
10 /***********************************************************************/
11 /**********************By Asm.Def-Wu Jiaxin*****************************/
12 /***********************************************************************/
13 #include <cstdio>
14 #include <cstring>
15 #include <cstdlib>
16 #include <ctime>
17 #include <cctype>
18 #include <algorithm>
19 #include <cmath>
20 using namespace std;
21 #define getc() getchar()
22 template<class T>inline void getd(T &x){
23 char ch = getc();bool neg = false;
24 while(!isdigit(ch) && ch != '-')ch = getc();
25 if(ch == '-')ch = getc(), neg = true;
26 x = ch - '0';
27 while(isdigit(ch = getc()))x = x * 10 - '0' + ch;
28 if(neg)x = -x;
29 }
30 /***********************************************************************/
31 #include <vector>
32 #include <queue>
33 #define pb push_back
34 #define pf push_front
35 const int maxn = 50005;
36 struct Edge{
37 int u, v, top, size;
38 void init(int a, int b){u = a, v = b;}
39 }E[maxn * 3], *Eend = E;
40 vector<Edge*>adj[maxn];
41 Edge *Last[maxn];
42 int dep[maxn], Ans, F[maxn], Stack[maxn], *Top = Stack;
43 bool istop[maxn];
44 struct Info{int val, id;Info(int a,int b){val = a, id = b;}};
45
46 inline void RollDP(int size){
47 int val[maxn<<1], N, i, mid = size >> 1, *it = val, Max = 0;
48 deque<Info> Q;
49 for(i = 0;i < size;++i)*it = F[Top[i]], Max = max(Max, min(i, size-i) + *(it++));
50 for(i = 0;i < mid;++i)*(it++) = F[Top[i]];
51 N = it - val;
52 Ans = max(Ans, *val);
53 Q.pb(Info(*val, 0));
54 for(i = 1;i < N;++i){
55 if(Q.front().id + mid < i)Q.pop_front();
56 Ans = max(Ans, Q.front().val + val[i] + i);
57 Info tmp(val[i]-i, i);
58 while(!Q.empty() && Q.back().val <= tmp.val)Q.pop_back();
59 Q.push_back(tmp);
60 }
61 F[*Top] = Max;
62 }
63
64 void dfs(int cur){
65 static bool vis[maxn];vis[cur] = true;
66 vector<Edge*>::iterator it;
67 for(it = adj[cur].begin();it != adj[cur].end();++it){
68 Edge &e = **it;
69 if(Last[cur] && e.v == Last[cur]->u)continue;
70 if(vis[e.v]){
71 if(dep[e.v] > dep[cur])continue;
72 Edge *t = &e;
73 int top = e.v, s = dep[cur] - dep[top] + 1;
74 do{
75 *(Top++) = t->v;
76 t->top = top, t->size = s;
77 t = Last[t->u];
78 }while(t && t->v != top);
79 }
80 else{
81 Last[e.v] = &e, dep[e.v] = dep[cur] + 1;
82 dfs(e.v);
83 if(!e.top){
84 Ans = max(Ans, F[cur] + F[e.v] + 1);
85 F[cur] = max(F[cur], F[e.v] + 1);
86 }
87 else if(e.top == cur){
88 while(*(--Top) != cur);
89 RollDP(e.size);
90 }
91 }
92 }
93 }
94
95 inline void work(){
96 int N, M, k, u, v;
97 getd(N);getd(M);
98 while(M--){
99 getd(k);getd(v);
while(--k){
u = v;getd(v);
Eend->init(u, v);adj[u].pb(Eend++);
Eend->init(v, u);adj[v].pb(Eend++);
}
}
dfs(1);
}

int main(){
work();
printf("%d\n", Ans);

#ifdef DEBUG
printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);
#endif
return 0;
}
仙人掌dp
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: