4 4 1 2 1 3 1 4 2 3 0 0
0
先 tarjan然后缩点得到一颗树,求树的直径就好了
#include <map> #include <set> #include <list> #include <stack> #include <vector> #include <queue> #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N = 200010; const int inf = 0x3f3f3f3f; const int M = 1000010; struct node { int next; int to; int id; }edge[M], edge2[M]; bool vis[N]; bool flag[N]; int dist[N]; int head[N]; int head2[N]; int low[N]; int block[N]; int DFN[N]; bool instack[N]; stack<int>qu; int br_cnt, n, m, end_p; int tot, tot2, maxs, index, top, sccnum; void addedge(int from, int to, int id) { edge[tot].id = id; edge[tot].to = to; edge[tot].next = head[from]; head[from] = tot++; } void addedge2(int from, int to) { edge2[tot].to = to; edge2[tot].next = head2[from]; head2[from] = tot++; } void init() { index = 0; sccnum = 0; top = 0; tot = 0; tot2 = 0; maxs = 0; br_cnt = 0; end_p = 0; memset ( head, -1, sizeof(head) ); memset (head2, -1, sizeof(head2) ); memset ( low, 0, sizeof(low) ); memset (DFN, 0, sizeof(DFN) ); memset ( instack, 0, sizeof(instack) ); memset ( flag, 0, sizeof(flag) ); memset (vis, 0, sizeof(vis) ); } void build() { int u, v; while (!qu.empty() ) { qu.pop(); } for (int i = 1; i <= m; ++i) { scanf("%d%d", &u, &v); addedge(u, v, i); addedge(v, u, i); } } void tarjan(int u, int fa) { qu.push(u); instack[u] = 1; DFN[u] = low[u] = ++index; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (fa == edge[i].id) { continue; } if ( !instack[v] ) { tarjan(v, edge[i].id); low[u] = min(low[u], low[v]); if (DFN[u] < low[v]) { br_cnt++; } } else { low[u] = min(DFN[v], low[u]); } } if (DFN[u] == low[u]) { sccnum++; int v; while(1) { v = qu.top(); qu.pop(); instack[v] = 0; block[v] = sccnum; if(v == u) { break; } } } } void bfs(int s) { queue<int>qu; while ( !qu.empty() ) { qu.pop(); } memset ( vis, 0, sizeof(vis) ); qu.push(s); dist[s] = 0; vis[s] = 1; maxs = 0; while ( !qu.empty() ) { int u = qu.front(); qu.pop(); for (int i = head2[u]; i != -1; i = edge2[i].next) { int v = edge2[i].to; if (!vis[v]) { vis[v] = 1; dist[v] = dist[u] + 1; qu.push(v); if (maxs < dist[v]) { maxs = dist[v]; end_p = v; } } } } } void solve() { for (int i = 1; i <= n; ++i) { if (DFN[i] == 0) { tarjan(i, -1); } } for (int u = 1; u <= n; ++u) { for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (block[u] != block[v]) { addedge2(block[u], block[v]); } } } bfs(1); bfs(end_p); printf("%d\n", br_cnt - maxs); } int main() { while (~scanf("%d%d", &n, &m)) { if (!n && !m) { break; } init(); build(); solve(); } return 0; }