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
  • 相关阅读:
    温故知新 将Date和String类型相互转换
    温故知新 线程
    温故知新 数组
    温故知新 集合
    温故知新 流(字节流与字符流)
    温故知新 jdbc 数据库调取封装
    Reds 持久化 高并发 高可用
    批量修改文件后缀名
    scala之旅-核心语言特性【高阶函数】(十)
    scala之旅-核心语言特性【使用混入组合类】(九)
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4393923.html
Copyright © 2011-2022 走看看