zoukankan      html  css  js  c++  java
  • Traffic Real Time Query System HDU

    https://vjudge.net/problem/HDU-3686

    点双啊,就是在求割顶的时候,另外用一个栈来存一些

    在遍历u点出发的边时,遇到树边或反向边(u,v)就把此边加入栈(可能要记一下边的编号)(但是,如果(u,v)是反过来看的反向边(此时dfn[v]>=dfn[u];实际反向边应该为(v,u))或者反过来的树边(此时k==(last^1))就不能加入)

    遇到一个割点,就多一个点双(不考虑因为(fa<0&&child==1)的特判而去掉的割点)

    计算(u,v)中遇到割点后,就不断从栈顶弹出边,直到栈顶的边与(u,v)相等,然后再弹出一个边;所有这些弹出的边以及边的两个端点都属于这个点双

    先对原图求点双连通分量,求出每条边属于的点双

    然后为原图中每一个点双新建一个点,向这个点双内每一个点连边,去掉原图所有边,得到一个新图(实际上是一棵树)

    询问两条边a,b时,先找出它们属于的点双对应的点编号x,y,那么答案就是新树上x与y的最短路径中"非点双对应的点"的数量(由于实际是要求这两个点双在原图中的路径间割点数量,而只有割点才可能成为新树中要统计的点)

    https://blog.csdn.net/u013480600/article/details/44835827

    错误记录:

    倍增写错。。。115行少d[anc[x][0]][0]

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<vector>
      5 using namespace std;
      6 #define fi first
      7 #define se second
      8 #define mp make_pair
      9 #define pb push_back
     10 typedef long long ll;
     11 typedef unsigned long long ull;
     12 typedef pair<int,int> pii;
     13 #define CLR(x) memset(x,0,sizeof(x))
     14 #define N 10100
     15 #define M 101000
     16 typedef pair<pii,int> ppi;
     17 struct E{int to,nxt;};
     18 namespace G
     19 {
     20 E e[M<<1];
     21 int f1[N],ne;
     22 int dfn[N],bno[N],dfc,cnt,bn2[M];bool iscut[N];
     23 ppi st[M];int top;
     24 vector<int> bcc[N];
     25 //#define D(x) ((x)&2147483646)
     26 void clr()
     27 {
     28     CLR(f1);ne=1;
     29     CLR(dfn);CLR(bno);CLR(iscut);CLR(bn2);dfc=cnt=top=0;
     30 }
     31 void me(int a,int b)
     32 {
     33     e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;
     34     e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;
     35 }
     36 int dfs(int u,int last)
     37 {
     38     int k,v,lowu=dfn[u]=++dfc,chi=0,lowv;ppi x;
     39     for(k=f1[u];k;k=e[k].nxt)
     40     {
     41         v=e[k].to;
     42         if(!dfn[v])
     43         {
     44             st[++top]=mp(mp(u,v),k);chi++;
     45             lowv=dfs(v,k);lowu=min(lowu,lowv);
     46             if(lowv>=dfn[u])
     47             {
     48                 iscut[u]=1;
     49                 cnt++;bcc[cnt].clear();
     50                 for(;;)
     51                 {
     52                     x=st[top--];
     53                     if(bno[x.fi.fi]!=cnt)
     54                         bno[x.fi.fi]=cnt,bcc[cnt].pb(x.fi.fi);
     55                     if(bno[x.fi.se]!=cnt)
     56                         bno[x.fi.se]=cnt,bcc[cnt].pb(x.fi.se);
     57                     bn2[x.se/2]=cnt;
     58                     if(x.fi.fi==u&&x.fi.se==v)    break;
     59                 }
     60             }
     61         }
     62         else if(dfn[v]<dfn[u]&&k!=(last^1))
     63         {
     64             st[++top]=mp(mp(u,v),k);
     65             lowu=min(lowu,dfn[v]);
     66         }
     67     }
     68     if(last<0&&chi==1)    iscut[u]=0;
     69     return lowu;
     70 }
     71 }
     72 int n,m,l2n=18,qq;
     73 namespace T
     74 {
     75 E e[N<<2];
     76 int f1[N<<1],ne;
     77 int anc[N<<1][22],d[N<<1][22],dep[N<<1];
     78 //d[i][j]表示i点到其2^j级祖先中(含i,不含祖先),共有几个圆点
     79 bool vis[N<<1];
     80 void clr()    {CLR(f1);CLR(anc);CLR(vis);CLR(d);CLR(dep);ne=1;}
     81 void me(int a,int b)
     82 {
     83     e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;
     84     e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;
     85 }
     86 void dfs(int u,int fa)
     87 {
     88     int i;
     89     vis[u]=1;anc[u][0]=fa;d[u][0]=(u<=n);
     90     for(i=1;i<=l2n;i++)
     91     {
     92         anc[u][i]=anc[anc[u][i-1]][i-1];
     93         d[u][i]=d[u][i-1]+d[anc[u][i-1]][i-1];
     94     }
     95     for(int k=f1[u];k;k=e[k].nxt)
     96         if(e[k].to!=fa)
     97         {
     98             dep[e[k].to]=dep[u]+1;
     99             dfs(e[k].to,u);
    100         }
    101 }
    102 int ask(int x,int y)
    103 {
    104     int t,i,ans=0;
    105     if(dep[x]<dep[y])    swap(x,y);
    106     for(t=dep[x]-dep[y],i=0;t>0;t>>=1,i++)
    107         if(t&1)    ans+=d[x][i],x=anc[x][i];
    108     if(x==y)    return ans;
    109     for(i=l2n;i>=0;i--)
    110         if(anc[x][i]!=anc[y][i])
    111         {
    112             ans+=(d[x][i]+d[y][i]);
    113             x=anc[x][i];y=anc[y][i];
    114         }
    115     ans+=(d[x][0]+d[y][0]+d[anc[x][0]][0]);
    116     return ans;
    117 }
    118 }
    119 int main()
    120 {
    121     int a,b,i,j;
    122     while(1)
    123     {
    124         G::clr();T::clr();
    125         scanf("%d%d",&n,&m);
    126         if(n==0&&m==0)    break;
    127         for(i=1;i<=m;i++)    scanf("%d%d",&a,&b),G::me(a,b);
    128         for(i=1;i<=n;i++)    if(!G::dfn[i])    G::dfs(i,-1);
    129         for(i=1;i<=G::cnt;i++)
    130             for(j=0;j<G::bcc[i].size();j++)
    131                 T::me(n+i,G::bcc[i][j]);
    132         for(i=1;i<=n+G::cnt;i++)
    133             if(!T::vis[i])
    134                 T::dfs(i,0);
    135         scanf("%d",&qq);
    136         while(qq--)
    137         {
    138             scanf("%d%d",&a,&b);
    139             printf("%d
    ",T::ask(n+G::bn2[a],n+G::bn2[b]));
    140         }
    141     }
    142     return 0;
    143 }
  • 相关阅读:
    PHP基础学习笔记(一)
    安装wampserver之后,浏览器中输入localhost页面显示IIS7解决办法
    HTML5常识总结(一)
    AngularJs中的服务
    AngularJs中的directives(指令part1)
    Happy Number——LeetCode
    Binary Tree Zigzag Level Order Traversal——LeetCode
    Construct Binary Tree from Preorder and Inorder Traversal——LeetCode
    Construct Binary Tree from Inorder and Postorder Traversal——LeetCode
    Convert Sorted Array to Binary Search Tree——LeetCode
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9288506.html
Copyright © 2011-2022 走看看