zoukankan      html  css  js  c++  java
  • HDU 4612 Warm up

    Warm up

    Time Limit: 5000ms
    Memory Limit: 65535KB
    This problem will be judged on HDU. Original ID: 4612
    64-bit integer IO format: %I64d      Java class name: Main
      N planets are connected by M bidirectional channels that allow instant transportation. It's always possible to travel between any two planets through these channels.
      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

      The input contains multiple cases.
      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

      For each case, output the minimal number of bridges after building a new channel in a line.
     

    Sample Input

    4 4
    1 2
    1 3
    1 4
    2 3
    0 0

    Sample Output

    0

    Source

     
    解题:类似于network那题。。。边双连通+树的直径
    此题严重爆栈。。。只能用微软的编译器
     
     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
    ",scc - 1 - d[bfs(bfs(1))]);
    95     }
    96     return 0;
    97 }
    View Code

    很容易想到树的直径就是某一点到两个最长点的和。。。

     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
    ",scc - 1 - ans);
    78     }
    79     return 0;
    80 }
    View Code
  • 相关阅读:
    Java学习之Jdk配置
    Socket网络模型之Select模型
    c#之初见反射
    c++读取文件夹中的文件
    C#泛型的初步理解
    C#接口简单介绍
    c#类,属性,方法和对象基本介绍
    事件的基本认识
    委托的基本认识
    在Xshell中使用rz命令上传文件出现乱码且文件无法删除的解决办法
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4393923.html
Copyright © 2011-2022 走看看