题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4612
Warm up
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 7206 Accepted Submission(s): 1681
If we can isolate some planets from others by breaking only one channel , the channel is called a bridge of the transportation system.
People don't like to be isolated. So they ask what's the minimal number of bridges they can have if they decide to build a new channel.
Note that there could be more than one channel between two planets.
Each case starts with two positive integers N and M , indicating the number of planets and the number of channels.
(2<=N<=200000, 1<=M<=1000000)
Next M lines each contains two positive integers A and B, indicating a channel between planet A and B in the system. Planets are numbered by 1..N.
A line with two integers '0' terminates the input.
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 using namespace std; 13 typedef long long LL; 14 const double EPS = 1e-8; 15 const int INF = 2e9; 16 const LL LNF = 2e18; 17 const int MAXN = 2e5+10; 18 19 struct Edge 20 { 21 int to, next; 22 }edge[MAXN*10]; 23 int tot, head[MAXN]; 24 vector<int>g[MAXN]; 25 26 void addedge(int u, int v) 27 { 28 edge[tot].to = v; 29 edge[tot].next = head[u]; 30 head[u] = tot++; 31 } 32 33 int index, dfn[MAXN], low[MAXN]; 34 int top, Stack[MAXN], instack[MAXN]; 35 int block, belong[MAXN]; 36 37 void Tarjan(int u, int pre) 38 { 39 dfn[u] = low[u] = ++index; 40 Stack[top++] = u; 41 instack[u] = true; 42 for(int i = head[u]; i!=-1; i = edge[i].next) 43 { 44 //因为一对点之间可能有多条边,所以不能根据v是否为上一个点来防止边是否被重复访问。而需要根据边的编号 45 if((i^1)==pre) continue; 46 int v = edge[i].to; 47 if(!dfn[v]) 48 { 49 Tarjan(v, i); 50 low[u] = min(low[u], low[v]); 51 } 52 else if(instack[v]) 53 low[u] = min(low[u], dfn[v]); 54 } 55 56 if(low[u]==dfn[u]) 57 { 58 block++; 59 int v; 60 do 61 { 62 v = Stack[--top]; 63 instack[v] = false; 64 belong[v] = block; 65 }while(v!=u); 66 } 67 } 68 69 int diameter, endpoint; 70 int dfs(int u, int pre, int dep) 71 { 72 if(dep>diameter) { endpoint = u; diameter = dep; } 73 for(int i = 0; i<g[u].size(); i++) 74 if(g[u][i]!=pre) 75 dfs(g[u][i], u, dep+1); 76 } 77 78 void init(int n) 79 { 80 tot = 0; 81 memset(head, -1, sizeof(head)); 82 83 index = 0; 84 memset(dfn, 0, sizeof(dfn)); 85 memset(low, 0, sizeof(low)); 86 87 top = 0; 88 memset(instack, false, sizeof(instack)); 89 90 block = 0; 91 for(int i = 1; i<=n; i++) 92 belong[i] = i, g[i].clear(); 93 } 94 95 int main() 96 { 97 int n, m; 98 while(scanf("%d%d", &n, &m) && (n||m) ) 99 { 100 init(n); 101 for(int i = 1; i<=m; i++) 102 { 103 int u, v; 104 scanf("%d%d", &u, &v); 105 addedge(u, v); 106 addedge(v, u); 107 } 108 109 Tarjan(1, -1); 110 for(int u = 1; u<=n; u++) 111 for(int i = head[u]; i!=-1; i = edge[i].next) 112 { 113 int v = edge[i].to; 114 if(belong[u]!=belong[v]) 115 g[belong[u]].push_back(belong[v]); 116 } 117 118 endpoint = 1, diameter = 0; 119 dfs(1, -1, 0); 120 dfs(endpoint, -1, 0); 121 printf("%d\n", block-1-diameter); 122 } 123 }
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 using namespace std; 13 typedef long long LL; 14 const double EPS = 1e-8; 15 const int INF = 2e9; 16 const LL LNF = 2e18; 17 const int MAXN = 2e5+10; 18 19 struct Edge 20 { 21 int from, to, next; 22 }edge[MAXN*10]; 23 int tot, head[MAXN]; 24 25 void addedge(int u, int v) 26 { 27 edge[tot].from = u; 28 edge[tot].to = v; 29 edge[tot].next = head[u]; 30 head[u] = tot++; 31 } 32 33 int index, dfn[MAXN], low[MAXN]; 34 int top, Stack[MAXN], instack[MAXN]; 35 int block, belong[MAXN]; 36 37 void Tarjan(int u, int pre) 38 { 39 dfn[u] = low[u] = ++index; 40 Stack[top++] = u; 41 instack[u] = true; 42 for(int i = head[u]; i!=-1; i = edge[i].next) 43 { 44 //因为一对点之间可能有多条边,所以不能根据v是否为上一个点来防止边是否被重复访问。而需要根据边的编号 45 if((i^1)==pre) continue; 46 int v = edge[i].to; 47 if(!dfn[v]) 48 { 49 Tarjan(v, i); 50 low[u] = min(low[u], low[v]); 51 } 52 else if(instack[v]) 53 low[u] = min(low[u], dfn[v]); 54 } 55 56 if(low[u]==dfn[u]) 57 { 58 block++; 59 int v; 60 do 61 { 62 v = Stack[--top]; 63 instack[v] = false; 64 belong[v] = block; 65 }while(v!=u); 66 } 67 } 68 69 int diameter, endpoint; 70 int dfs(int u, int pre, int dep) 71 { 72 if(dep>diameter) { endpoint = u; diameter = dep; } 73 for(int i = head[u]; i!=-1; i = edge[i].next) 74 if(edge[i].to!=pre) 75 dfs(edge[i].to, u, dep+1); 76 } 77 78 void init(int n) 79 { 80 tot = 0; 81 memset(head, -1, sizeof(head)); 82 83 index = 0; 84 memset(dfn, 0, sizeof(dfn)); 85 memset(low, 0, sizeof(low)); 86 87 top = 0; 88 memset(instack, false, sizeof(instack)); 89 90 block = 0; 91 for(int i = 1; i<=n; i++) 92 belong[i] = i; 93 } 94 95 int main() 96 { 97 int n, m; 98 while(scanf("%d%d", &n, &m) && (n||m) ) 99 { 100 init(n); 101 for(int i = 1; i<=m; i++) 102 { 103 int u, v; 104 scanf("%d%d", &u, &v); 105 addedge(u, v); 106 addedge(v, u); 107 } 108 109 Tarjan(1, -1); 110 tot = 0; 111 memset(head, -1, sizeof(head)); 112 for(int i = 0; i<2*m; i++) 113 { 114 int u = edge[i].from, v = edge[i].to; 115 if(belong[u]!=belong[v]) 116 addedge(belong[u], belong[v]); 117 } 118 119 endpoint = 1, diameter = 0; 120 dfs(1, -1, 0); 121 dfs(endpoint, -1, 0); 122 printf("%d\n", block-1-diameter); 123 } 124 }