【HDOJ】4612 Warm up

双连通缩点+求树的直径,图论基础题目。

复制代码
  1 /* 4612 */
  2 #pragma comment(linker, "/STACK:1024000000,1024000000")
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <queue>
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <cstdlib>
 10 using namespace std;
 11 
 12 #define MAXV 200005
 13 #define MAXE 1000005
 14 
 15 typedef struct {
 16     int v, next;
 17 } Edge_t;
 18 
 19 Edge_t E[MAXE*2];
 20 vector<int> vc[MAXV];
 21 int low[MAXV], pre[MAXV];
 22 int bn[MAXV];
 23 int S[MAXV], top;
 24 int head[MAXV], L;
 25 bool visit[MAXV];
 26 int dfs_clock, block;
 27 int n, m;
 28 
 29 void addEdge(int u, int v) {
 30     E[L].v = v;
 31     E[L].next = head[u];
 32     head[u] = L++;
 33 }
 34 
 35 void init() {
 36     memset(head, -1, sizeof(int)*(n+1));
 37     memset(pre, 0, sizeof(int)*(n+1));
 38     memset(bn, 0, sizeof(int)*(n+1));
 39     dfs_clock = block = L = top = 0;
 40 }
 41 
 42 void tarjan(int u, int fa) {
 43     int i, j, k, v;
 44     
 45     S[top++] = u;
 46     pre[u] = low[u] = ++dfs_clock;
 47     for (i=head[u]; i!=-1; i=E[i].next) {
 48         if (i == (fa^1))
 49             continue;
 50         v = E[i].v;
 51         if (!pre[v]) {
 52             tarjan(v, i);
 53             low[u] = min(low[u], low[v]);
 54         } else if (!bn[v]) {
 55             low[u] = min(low[u], pre[v]);
 56         }
 57     }
 58     if (low[u] == pre[u]) {
 59         ++block;
 60         do {
 61             bn[S[--top]] = block;
 62         } while (S[top]!=u);
 63     }
 64 }
 65 
 66 void solve() {
 67     queue<int> Q;
 68     int i, j, k;
 69     int u = 1, v;
 70     
 71     memset(pre, 0, sizeof(int)*(block+1));
 72     pre[u] = 1;
 73     Q.push(u);
 74     while (!Q.empty()) {
 75         u = Q.front();
 76         Q.pop();
 77         for (i=0; i<vc[u].size(); ++i) {
 78             v = vc[u][i];
 79             if (!pre[v]) {
 80                 pre[v] = 1;
 81                 Q.push(v);
 82             }
 83         }
 84     }
 85     
 86     memset(pre, 0, sizeof(int)*(block+1));
 87     pre[u] = 1;
 88     Q.push(u);
 89     while (!Q.empty()) {
 90         u = Q.front();
 91         Q.pop();
 92         k = pre[u];
 93         for (i=0; i<vc[u].size(); ++i) {
 94             v = vc[u][i];
 95             if (!pre[v]) {
 96                 pre[v] = k+1;
 97                 Q.push(v);
 98             }
 99         }
100     }
101     
102     printf("%d\n", block-pre[u]);
103 }
104 
105 int main() {
106     int i, j, k;
107     
108     #ifndef ONLINE_JUDGE
109         freopen("data.in", "r", stdin);
110         freopen("data.out", "w", stdout);
111     #endif
112     
113     while (scanf("%d %d",&n,&m)!=EOF && (n||m)) {
114         init();
115         for (i=0; i<m; ++i) {
116             scanf("%d %d", &j, &k);
117             addEdge(j, k);
118             addEdge(k, j);
119         }
120         for (i=1; i<=n; ++i)
121             if (!pre[i])
122                 tarjan(i, -1);
123         for (i=1; i<=block; ++i)
124             vc[i].clear();
125         for (i=1; i<=n; ++i) {
126             for (j=head[i]; j!=-1; j=E[j].next) {
127                 k = E[j].v;
128                 if (bn[i] != bn[k]) {
129                     // bridge
130                     vc[bn[i]].push_back(bn[k]);
131                     vc[bn[k]].push_back(bn[i]);
132                 }
133             }
134         }
135         solve();
136     }
137     
138     return 0;
139 }
复制代码

 

posted on   Bombe  阅读(149)  评论(0编辑  收藏  举报

编辑推荐:
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
阅读排行:
· 为DeepSeek添加本地知识库
· 精选4款基于.NET开源、功能强大的通讯调试工具
· DeepSeek智能编程
· 大模型工具KTransformer的安装
· [计算机/硬件/GPU] 显卡
历史上的今天:
2014-03-20 【原创翻译】The Case for the Reduced Instruction Set Computer
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

导航

统计

点击右上角即可分享
微信分享提示