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
  • 相关阅读:
    zoj 3135 Party of 8g 最大点权独立集
    hdu 5352 MZL's City 最小费用最大流
    hdu 5351 MZL's Border 打表+高精度
    poj 3155 Hard Life 最大密度子图
    希尔排序的温习
    折半查找法的温习
    几所可能去的院校之对比与抉择
    重温排序算法
    5-17 汉诺塔的非递归实现 (25分)
    c语言从文件中读取数据作为输入
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4393923.html
Copyright © 2011-2022 走看看