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

    果断对Tarjan不熟啊,Tarjan后缩点,求树上的最长路,注意重边的处理,借鉴宝哥的做法,开标记数组,标记自己的反向边。

      1 #pragma comment(linker, "/STACK:1024000000,1024000000")
      2 #include <iostream>
      3 #include <cstring>
      4 #include <cstdio>
      5 #include <queue>
      6 #include <cstdlib>
      7 using namespace std;
      8 #define N 200001
      9 #define M 2000001
     10 #define INF 0x3f3f3f3f
     11 struct node
     12 {
     13     int u,v,next;
     14 }edge[M];
     15 struct na
     16 {
     17     int u,v,w,next;
     18 }tree[M];
     19 int first[N],DFN[N],Belong[N],stack[N],Low[N],cnum[N];
     20 int in[N],d[N],fr[N];
     21 int qu[M],qv[M];
     22 int n,m;
     23 bool vis[M];
     24 int tot,scnt,top;
     25 void CL()
     26 {
     27     tot = scnt = top = 0;
     28     memset(first,-1,sizeof(first));
     29     memset(fr,-1,sizeof(fr));
     30     memset(in,0,sizeof(in));
     31     memset(DFN,0,sizeof(DFN));
     32     memset(vis,0,sizeof(vis));
     33 }
     34 void add(int u,int v)
     35 {
     36     edge[tot].u = u;
     37     edge[tot].v = v;
     38     edge[tot].next = first[u];
     39     first[u] = tot ++;
     40 }
     41 void addt(int u,int v)
     42 {
     43     tree[tot].u = u;
     44     tree[tot].v = v;
     45     tree[tot].w = 1;
     46     tree[tot].next = fr[u];
     47     fr[u] = tot ++;
     48 }
     49 void Tarjan(int u,int num)
     50 {
     51     int v,i;
     52     DFN[u] = Low[u] = ++ tot;
     53     stack[top++] = u;
     54     in[u] = 1;
     55     for(i = first[u];i != -1;i = edge[i].next)
     56     {
     57         v = edge[i].v;
     58         if(vis[i]) continue;
     59         vis[i] = vis[i^1] = 1;
     60         if(!DFN[v])
     61         {
     62             //printf("cc%d %d",v,i);
     63             Tarjan(v,i);
     64             Low[u] = min(Low[u],Low[v]);
     65         }
     66         else if(in[v])
     67         {
     68             Low[u] = min(Low[u],DFN[v]);
     69         }
     70     }
     71     if(DFN[u] == Low[u])
     72     {
     73         scnt ++;
     74         do
     75         {
     76             v = stack[--top];
     77             Belong[v] = scnt;
     78             in[v] = 0;
     79             cnum[scnt] ++;
     80         }while(u != v);
     81     }
     82 }
     83 int spfa(int x)
     84 {
     85     int i,key,v,u,minz = 0;
     86     for(i = 1;i <= scnt;i ++)
     87     {
     88         in[i] = 0;
     89         d[i] = INF;
     90     }
     91     queue<int> que;
     92     in[x] = 1;
     93     d[x] = 0;
     94     que.push(x);
     95     while(!que.empty())
     96     {
     97         u = que.front();
     98         in[u] = 0;
     99         que.pop();
    100         for(i = fr[u];i != -1;i = tree[i].next)
    101         {
    102             v = tree[i].v;
    103             if(d[v] > d[u] + tree[i].w)
    104             {
    105                 d[v] = d[u] + tree[i].w;
    106                 if(!in[v])
    107                 {
    108                     in[v] = 1;
    109                     que.push(v);
    110                 }
    111             }
    112         }
    113     }
    114     for(i = 1;i <= scnt;i ++)
    115     {
    116         if(minz < d[i])
    117         {
    118             minz = d[i];
    119             key = i;
    120         }
    121     }
    122     return key;
    123 }
    124 int main()
    125 {
    126    
    127     int i,u,v,str,x;
    128     while(scanf("%d%d",&n,&m)!=EOF)
    129     {
    130         if(n == 0&&m == 0) break;
    131         CL();
    132         for(i = 1;i <= m;i ++)
    133         {
    134             scanf("%d%d",&u,&v);
    135             if(i == 1)
    136             str = u;
    137             qu[i] = u;
    138             qv[i] = v;
    139             add(u,v);
    140             add(v,u);
    141         }
    142         tot = 0;
    143         Tarjan(u,0);
    144         tot = 0;
    145         for(i = 1;i <= m;i ++)
    146         {
    147             if(Belong[qu[i]] != Belong[qv[i]])
    148             {
    149                 addt(Belong[qu[i]],Belong[qv[i]]);
    150                 addt(Belong[qv[i]],Belong[qu[i]]);
    151             }
    152         }
    153         if(scnt == 1)
    154         printf("0
    ");
    155         else
    156         {
    157             x = spfa(spfa(1));
    158             printf("%d
    ",scnt-d[x]-1);
    159         }
    160     }
    161     return 0;
    162 }
  • 相关阅读:
    二分法查找数据
    循环队列的操作
    堆栈的操作
    链表的各种操作
    尾插法创建链表
    头插法创建链表
    链表简介
    <map>的常用操作
    linux下php添加自带扩展
    快速排序
  • 原文地址:https://www.cnblogs.com/naix-x/p/3218971.html
Copyright © 2011-2022 走看看