Warm up
64-bit integer IO format: %I64d Java class name: Main
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.
Input
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.
Output
Sample Input
4 4 1 2 1 3 1 4 2 3 0 0
Sample Output
0
Source
1 #pragma comment(linker, "/STACK:102400000,102400000") 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <stack> 7 using namespace std; 8 const int maxn = 200010; 9 struct arc{ 10 int to,next; 11 arc(int x = 0,int y = -1){ 12 to = x; 13 next = y; 14 } 15 }e[4000000]; 16 int head[maxn],hd[maxn],dfn[maxn],low[maxn],belong[maxn]; 17 int scc,idx,tot,n,m,d[maxn]; 18 bool instack[maxn]; 19 stack<int>stk; 20 void add(int *head,int u,int v){ 21 e[tot] = arc(v,head[u]); 22 head[u] = tot++; 23 } 24 void tarjan(int u,int fa){ 25 dfn[u] = low[u] = ++idx; 26 instack[u] = true; 27 stk.push(u); 28 bool flag = true; 29 for(int i = head[u]; ~i; i = e[i].next){ 30 if(e[i].to == fa && flag){ 31 flag = false; 32 continue; 33 } 34 if(!dfn[e[i].to]){ 35 tarjan(e[i].to,u); 36 low[u] = min(low[u],low[e[i].to]); 37 }else if(instack[e[i].to]) low[u] = min(low[u],dfn[e[i].to]); 38 } 39 if(low[u] == dfn[u]){ 40 scc++; 41 int v; 42 do{ 43 instack[v = stk.top()] = false; 44 stk.pop(); 45 belong[v] = scc; 46 }while(v != u); 47 } 48 } 49 void init(){ 50 for(int i = 0; i < maxn; ++i){ 51 head[i] = hd[i] = -1; 52 belong[i] = low[i] = dfn[i] = 0; 53 instack[i] = false; 54 } 55 idx = scc = tot = 0; 56 while(!stk.empty()) stk.pop(); 57 } 58 queue<int>q; 59 int bfs(int u){ 60 while(!q.empty()) q.pop(); 61 memset(d,-1,sizeof(d)); 62 d[u] = 0; 63 q.push(u); 64 while(!q.empty()){ 65 u = q.front(); 66 q.pop(); 67 for(int i = hd[u]; ~i; i = e[i].next){ 68 if(d[e[i].to] == -1){ 69 d[e[i].to] = d[u] + 1; 70 q.push(e[i].to); 71 } 72 } 73 } 74 int maxV = 0,idx = u; 75 for(int i = 1; i <= scc; ++i) 76 if(d[i] > maxV) maxV = d[idx = i]; 77 return idx; 78 } 79 int main(){ 80 int u,v; 81 while(scanf("%d %d",&n,&m),n||m){ 82 init(); 83 for(int i = 0; i < m; ++i){ 84 scanf("%d %d",&u,&v); 85 add(head,u,v); 86 add(head,v,u); 87 } 88 tarjan(1,-1); 89 for(int i = 1; i <= n; ++i) 90 for(int j = head[i]; ~j; j = e[j].next){ 91 if(belong[i] != belong[e[j].to]) 92 add(hd,belong[i],belong[e[j].to]); 93 } 94 printf("%d\n",scc - 1 - d[bfs(bfs(1))]); 95 } 96 return 0; 97 }
很容易想到树的直径就是某一点到两个最长点的和。。。
1 #pragma comment(linker, "/STACK:102400000,102400000") 2 #include <iostream> 3 #include <queue> 4 #include <cstdio> 5 #include <cstring> 6 #include <stack> 7 using namespace std; 8 const int maxn = 200010; 9 struct arc { 10 int to,next; 11 arc(int x = 0,int y = -1) { 12 to = x; 13 next = y; 14 } 15 } e[4000000]; 16 int head[maxn],dfn[maxn],low[maxn],belong[maxn]; 17 int scc,idx,tot,n,m,dp[maxn][2]; 18 bool instack[maxn]; 19 stack<int>stk; 20 void add(int *head,int u,int v) { 21 e[tot] = arc(v,head[u]); 22 head[u] = tot++; 23 } 24 void tarjan(int u,int fa) { 25 dfn[u] = low[u] = ++idx; 26 instack[u] = true; 27 stk.push(u); 28 dp[u][0] = dp[u][1] = 0; 29 bool flag = true; 30 for(int i = head[u]; ~i; i = e[i].next) { 31 if(e[i].to == fa && flag) { 32 flag = false; 33 continue; 34 } 35 if(!dfn[e[i].to]) { 36 tarjan(e[i].to,u); 37 low[u] = min(low[u],low[e[i].to]); 38 int tmp = dp[e[i].to][1] + (low[e[i].to] > dfn[u]); 39 if(tmp > dp[u][1]) { 40 swap(dp[u][1],dp[u][0]); 41 dp[u][1] = tmp; 42 } else if(tmp > dp[u][0]) dp[u][0] = tmp; 43 } else if(instack[e[i].to]) low[u] = min(low[u],dfn[e[i].to]); 44 } 45 if(low[u] == dfn[u]) { 46 scc++; 47 int v; 48 do { 49 instack[v = stk.top()] = false; 50 stk.pop(); 51 belong[v] = scc; 52 } while(v != u); 53 } 54 } 55 void init() { 56 for(int i = 0; i < maxn; ++i) { 57 head[i] = -1; 58 belong[i] = low[i] = dfn[i] = 0; 59 instack[i] = false; 60 } 61 idx = scc = tot = 0; 62 while(!stk.empty()) stk.pop(); 63 } 64 int main() { 65 int u,v; 66 while(scanf("%d %d",&n,&m),n||m) { 67 init(); 68 for(int i = 0; i < m; ++i) { 69 scanf("%d %d",&u,&v); 70 add(head,u,v); 71 add(head,v,u); 72 } 73 tarjan(1,-1); 74 int ans = 0; 75 for(int i = 1; i <= n; ++i) 76 ans = max(ans,dp[i][1] + dp[i][0]); 77 printf("%d\n",scc - 1 - ans); 78 } 79 return 0; 80 }