bzoj1023 [SHOI2008]cactus仙人掌图

1023: [SHOI2008]cactus仙人掌图

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 1495  Solved: 608

Description

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

 

举例来说,上面的第一个例子是一张仙人图,而第二个不是——注意到它有三条简单回路:(4,3,2,1,6,5,4)、(7,8,9,10,2,3,7)以及(4,3,7,8,9,10,2,1,6,5,4),而(2,3)同时出现在前两个的简单回路里。另外,第三张图也不是仙人图,因为它并不是连通图。显然,仙人图上的每条边,或者是这张仙人图的桥(bridge),或者在且仅在一个简单回路里,两者必居其一。定义在图上两点之间的距离为这两点之间最短路径的距离。定义一个图的直径为这张图相距最远的两个点的距离。现在我们假定仙人图的每条边的权值都是1,你的任务是求出给定的仙人图的直径。

Input

输入的第一行包括两个整数n和m(1≤n≤50000以及0≤m≤10000)。其中n代表顶点个数,我们约定图中的顶点将从1到n编号。接下来一共有m行。代表m条路径。每行的开始有一个整数k(2≤k≤1000),代表在这条路径上的顶点个数。接下来是k个1到n之间的整数,分别对应了一个顶点,相邻的顶点表示存在一条连接这两个顶点的边。一条路径上可能通过一个顶点好几次,比如对于第一个样例,第一条路径从3经过8,又从8返回到了3,但是我们保证所有的边都会出现在某条路径上,而且不会重复出现在两条路径上,或者在一条路径上出现两次。

Output

只需输出一个数,这个数表示仙人图的直径长度。

Sample Input

15 3
9 1 2 3 4 5 6 7 8 3
7 2 9 10 11 12 13 10
5 2 14 9 15 10 8
10 1
10 1 2 3 4 5 6 7 8 9 10

Sample Output

9

HINT

 

对第一个样例的说明:如图,6号点和12号点的最短路径长度为8,所以这张图的直径为8。


 


【注意】使用Pascal语言的选手请注意:你的程序在处理大数据的时候可能会出现栈溢出。如果需要调整栈空间的大小,可以在程序的开头填加一句:{$M 5000000},其中5000000即指代栈空间的大小,请根据自己的程序选择适当的数值。

 

Source

 

题意:给出一个图,图上有可能有环,每两个环最多只有一个公共点,不存在大环包小环的情况(废话,与前一句重复),问这个图的直径(任意两点的最短路径  的 最长值)

解法:把每一个环都找出来,然后计算环上两点这样的直径,用DP[x]表示从这个点出发(不走环上的点)的最长,然后加起来更新答案,对于每一个点,记录从这个点出发(不走父亲点) 的最长和次长,然后加起来更新答案。

 

然而,我wrong answer了,虽然跟admin拿了数据,但这并没有什么卵用,因为数据都是超大的数据,总有5个点过不了,查不出原因

在这里放上我的代码,重写了两遍了。。。。希望大神指点一下错误

 

放一下我没有AC的代码,希望大神指点一下错误

这是非递归的版本

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <deque>
  6 #include <vector>
  7 #include <queue>
  8 #include <iostream>
  9 #include <algorithm>
 10 #include <map>
 11 #include <set>
 12 #include <ctime>
 13 using namespace std;
 14 typedef long long LL;
 15 typedef double DB;
 16 #define For(i, s, t) for(int i = (s); i <= (t); i++)
 17 #define Ford(i, s, t) for(int i = (s); i >= (t); i--)
 18 #define Rep(i, t) for(int i = (0); i < (t); i++)
 19 #define Repn(i, t) for(int i = ((t)-1); i >= (0); i--)
 20 #define rep(i, x, t) for(int i = (x); i < (t); i++)
 21 #define MIT (2147483647)
 22 #define INF (1000000001)
 23 #define MLL (1000000000000000001LL)
 24 #define sz(x) ((int) (x).size())
 25 #define clr(x, y) memset(x, y, sizeof(x))
 26 #define puf push_front
 27 #define pub push_back
 28 #define pof pop_front
 29 #define pob pop_back
 30 #define ft first
 31 #define sd second
 32 #define mk make_pair
 33 inline void SetIO(string Name) {
 34     string Input = Name+".in",
 35     Output = Name+".out";
 36     freopen(Input.c_str(), "r", stdin),
 37     freopen(Output.c_str(), "w", stdout);
 38 }
 39 
 40 const int N = 50010, M = 200010;
 41 int First[N], To[M], Next[M], Tot;
 42 int n, m;
 43 int Circle[2*N], Scir, Len;
 44 int Dfn[N], Low[N], Tag, WhoVisit[N];
 45 int Dp[N], Ans;
 46 
 47 inline void Insert(int u, int v) {
 48     Tot++;
 49     To[Tot] = v, Next[Tot] = First[u];
 50     First[u] = Tot;
 51 }
 52 
 53 inline void Input() {
 54     scanf("%d%d", &n, &m);
 55     For(i, 1, m) {
 56         int l, u, v;
 57         scanf("%d%d", &l, &u);
 58         l--;
 59         while(l--) {
 60             scanf("%d", &v);
 61             Insert(u, v), Insert(v, u);
 62             u = v;
 63         }
 64     }
 65 }
 66 
 67 int Que[N];
 68 inline void Work() {
 69     For(i, 1, Scir) Circle[Scir+i] = Circle[i];
 70     int Head, Tail, x;
 71     Head = Tail = 1, Que[1] = 1;
 72     For(i, 2, Scir*2) {
 73         x = Circle[i];
 74         while(Head <= Tail && i-Que[Head] > Scir/2) Head++;
 75         if(Head <= Tail) Ans = max(Ans, Dp[x]+i+Dp[Circle[Que[Head]]]-Que[Head]);
 76         while(Head <= Tail && Dp[Que[Tail]]-Que[Tail] <= Dp[x]-i) Tail--;
 77         Que[++Tail] = i;
 78     }
 79 }
 80 
 81 inline void Updata(int &A, int &B, int C) {
 82     if(A < C) {
 83         B = A;
 84         A = C;
 85     } else if(B < C) B = C;
 86 }
 87 
 88 typedef pair<int, int> State;
 89 State Stack[N];
 90 int top, Sta[N], Size, Cnt[N];
 91 bool EverCircle[N];
 92 inline void Tarjan() {
 93     Stack[1] = State(1, 0), top = 1, Tag = 0, Size = 1, Sta[1] = 1;
 94     while(top) {
 95         int u = Stack[top].ft, fa = Stack[top].sd;
 96         if(!Dfn[u]) Dfn[u] = Low[u] = ++Tag, EverCircle[u] = 0, Cnt[u] = 0;
 97         
 98         bool Finish = 1, GoOn = 0;
 99         int Tab = First[u], v;
100         if(Tab) {
101             if((v = To[Tab]) != fa) {
102                 if(!Dfn[v]) {
103                     Stack[++top] = State(v, u), Sta[++Size] = v;
104                     WhoVisit[v] = u;
105                     GoOn = 1;
106                 } else if(WhoVisit[v] == u) {
107                     Low[u] = min(Low[u], Low[v]);
108                     if(Low[v] > Dfn[u]) {
109                         Size--;
110                         Updata(Dp[u], Cnt[u], Dp[v]+1);
111                     } else if(Low[v] == Dfn[u]) {
112                         for(Scir = 0; Sta[Size] != u; Circle[++Scir] = Sta[Size--]);
113                         Circle[++Scir] = u;
114                         Work();
115                         int Dis = 0;
116                         Ford(i, Scir-1, 1) Dis = max(Dis, Dp[Circle[i]]+min(i, Scir-i));
117                         Updata(Dp[u], Cnt[u], Dis);
118                     }
119                 } else Low[u] = min(Low[u], Dfn[v]);
120             }
121             Finish = 0;
122         }
123         
124         if(GoOn) continue;
125         if(!Finish) {
126             First[u] = Next[First[u]];
127             continue;
128         }
129         Stack[top--] = State(0, 0);
130         //Ans = max(Ans, Dp[u]+Cnt[u]);
131         if(Ans < Dp[u]+Cnt[u]) {
132             Ans = Dp[u]+Cnt[u];
133             //printf("Ans: %d    Id: %d\n", Ans, u);
134         }
135     }
136 }
137 
138 inline void Solve() {
139     Tarjan();
140     
141     printf("%d\n", Ans);
142 }
143 
144 int main() {
145     SetIO("cactus");
146     Input();
147     Solve();
148     return 0;
149 }
View Code

这是递归版本

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <deque>
  6 #include <vector>
  7 #include <queue>
  8 #include <iostream>
  9 #include <algorithm>
 10 #include <map>
 11 #include <set>
 12 #include <ctime>
 13 using namespace std;
 14 typedef long long LL;
 15 typedef double DB;
 16 #define For(i, s, t) for(int i = (s); i <= (t); i++)
 17 #define Ford(i, s, t) for(int i = (s); i >= (t); i--)
 18 #define Rep(i, t) for(int i = (0); i < (t); i++)
 19 #define Repn(i, t) for(int i = ((t)-1); i >= (0); i--)
 20 #define rep(i, x, t) for(int i = (x); i < (t); i++)
 21 #define MIT (2147483647)
 22 #define INF (1000000001)
 23 #define MLL (1000000000000000001LL)
 24 #define sz(x) ((int) (x).size())
 25 #define clr(x, y) memset(x, y, sizeof(x))
 26 #define puf push_front
 27 #define pub push_back
 28 #define pof pop_front
 29 #define pob pop_back
 30 #define ft first
 31 #define sd second
 32 #define mk make_pair
 33 inline void SetIO(string Name) {
 34     string Input = Name+".in",
 35     Output = Name+".out";
 36     freopen(Input.c_str(), "r", stdin),
 37     freopen(Output.c_str(), "w", stdout);
 38 }
 39 
 40 const int N = 50010, M = 200010;
 41 int n, m;
 42 int First[N], To[M], Next[M], Tot;
 43 int Dp[N], Ans;
 44 
 45 inline void Insert(int u, int v) {
 46     Tot++;
 47     To[Tot] = v, Next[Tot] = First[u];
 48     First[u] = Tot;
 49 }
 50 
 51 inline void Input() {
 52     scanf("%d%d", &n, &m);
 53     while(m--) {
 54         int k, u, v;
 55         for(scanf("%d%d", &k, &u); --k; u = v) {
 56             scanf("%d", &v);
 57             Insert(u, v), Insert(v, u);
 58         }
 59     }
 60 }
 61 
 62 inline void Updata(int &A, int &B, int C) {
 63     if(C > A) {
 64         B = A;
 65         A = C;
 66     } else if(C > B) B = C;
 67 }
 68 
 69 int Arr[N], Len, Que[N], Head, Tail;
 70 inline void Work() {
 71     For(i, 1, Len) Arr[i+Len] = Arr[i];
 72     Head = Tail = 1, Que[1] = 1;
 73     For(i, 2, Len*2) {
 74         while(i-Que[Head] > Len/2) Head++;
 75         Ans = max(Ans, Dp[Arr[Que[Head]]]+Dp[Arr[i]]+i-Que[Head]);
 76         while(Head <= Tail && Dp[Arr[i]]-i > Dp[Arr[Que[Tail]]]-Que[Tail]) Tail--;
 77         Que[++Tail] = i;
 78     }
 79 }
 80 
 81 int Dfn[N], Low[N], Time, Stack[N], top;
 82 inline void Search(int u, int fa) {
 83     int Cnt = 0;
 84     Dfn[u] = Low[u] = ++Time, Stack[++top] = u;
 85     for(int Tab = First[u], v; Tab; Tab = Next[Tab])
 86             if((v = To[Tab]) != fa) {
 87                 if(Dfn[v]) Low[u] = min(Low[u], Dfn[v]);
 88                 else {
 89                     Search(v, u);
 90                     Low[u] = min(Low[u], Low[v]);
 91                     if(Dfn[u] < Low[v]) {
 92                         top--;
 93                         Updata(Dp[u], Cnt, Dp[v]+1);
 94                     } else if(Dfn[u] == Low[v]) {
 95                         int x = 0;
 96                         for(Len = 0; Stack[top] != u; Arr[++Len] = Stack[top--]) ;
 97                         Arr[++Len] = u;
 98                         Work();
 99                         For(i, 1, Len-1) x = max(x, Dp[Arr[i]]+min(i, Len-i));
100                         Updata(Dp[u], Cnt, x);
101                     }
102                 }
103             }
104     Ans = max(Ans, Dp[u]+Cnt);
105 }
106 
107 inline void Solve() {
108     Search(1, 0);
109     printf("%d\n", Ans);
110 }
111 
112 int main() {
113     SetIO("1023");
114     Input();
115     Solve();
116     return 0;
117 }
View Code

 

posted @ 2015-08-26 12:23  yanzx6  阅读(186)  评论(0编辑  收藏  举报