1. 程式人生 > >Traffic Real Time Query System HDU - 3686

Traffic Real Time Query System HDU - 3686

cond cstring traffic div fine note spa cut sig

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

先對原圖求點雙連通分量,求出每條邊屬於的點雙

然後為原圖中每一個點雙新建一個點,向這個點雙內每一個點連邊,去掉原圖所有邊,得到一個新圖(實際上是一棵樹)

詢問兩條邊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\n",T::ask(n+G::bn2[a],n+G::bn2[b])); 140 } 141 } 142 return 0; 143 }

Traffic Real Time Query System HDU - 3686