• 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 }
  • 相关阅读:
    CSS3圆圈动画放大缩小循环动画效果
    php将多个值的数组去除重复元素
    .net 图片压缩
    关于FFmpegInterop项目的编译
    Axure Beta 7.0 汉化版下载
    axure 6.5 汉化正式版软件及注册码
    HTML基础复习(八)表单
    HTML基础复习(七)布局-div间距
    Android+GPS轨迹跟踪器(一)
    HTML基础复习(六)布局-居中
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9288506.html
Copyright © 2020-2023  润新知