JZOJ 5305. 【NOIP2017提高A组模拟8.18】C
生活随笔
收集整理的這篇文章主要介紹了
JZOJ 5305. 【NOIP2017提高A组模拟8.18】C
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Description
Input
Output
Sample Input
10 11
1 2
2 3
3 4
1 4
3 5
5 6
8 6
8 7
7 6
7 9
9 10
6
1 2
3 5
6 9
9 2
9 3
9 10
Sample Output
2
2
2
4
4
1
Data Constraint
Hint
Solution
由于“任意一個點最多只屬于一個簡單環(huán)”,于是我們先用 Tarjan 算法縮環(huán)為點,方便處理。
之后對縮環(huán)后的圖處理出倍增信息,對環(huán)所在的點打一個“1”標(biāo)記(表示1的貢獻)。
那么倍增統(tǒng)計出路徑上的“1”的個數(shù) k ,那么答案即為 2k ,時間復(fù)雜度 O(NlogN) 。
Code
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=100001,mo=1e9+7; int tot,top,now; int first[N],next[N<<1],en[N<<1]; int u[N*3/2],v[N*3/2]; int bel[N],p[N],dep[N]; int stack[N],dfn[N],low[N]; int f[N][17],g[N][17]; bool bz[N]; inline int read() {int X=0,w=1; char ch=0;while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();return X*w; } inline int write(int x) {if(x>9) write(x/10);putchar(x%10+'0'); } inline int min(int x,int y) {return x<y?x:y; } inline void insert(int x,int y) {next[++tot]=first[x];first[x]=tot;en[tot]=y; } inline void tarjan(int x,int y) {dfn[x]=low[x]=++now;bz[stack[++top]=x]=true;for(int i=first[x];i;i=next[i])if(en[i]!=y)if(!dfn[en[i]]){tarjan(en[i],x);low[x]=min(low[x],low[en[i]]);}elseif(bz[en[i]]) low[x]=min(low[x],dfn[en[i]]);if(dfn[x]==low[x]){g[x][0]=stack[top]!=x;do{bel[stack[top]]=x;bz[stack[top--]]=false;}while(stack[top+1]!=x);} } inline void dfs(int x) {dep[x]=dep[f[x][0]]+1;for(int i=first[x];i;i=next[i])if(en[i]!=f[x][0]){f[en[i]][0]=x;dfs(en[i]);} } inline int lca(int x,int y) {if(dep[x]<dep[y]) swap(x,y);int sum=0;for(int i=log2(dep[x]);i>=0;i--)if(dep[f[x][i]]>=dep[y]) sum+=g[x][i],x=f[x][i];if(x==y) return sum+g[x][0];for(int i=log2(dep[x]);i>=0;i--)if(f[x][i]!=f[y][i]) sum+=g[x][i]+g[y][i],x=f[x][i],y=f[y][i];sum+=g[x][0]+g[y][0];return sum+g[f[x][0]][0]; } int main() {int n=read(),m=read();for(int i=1;i<=m;i++){u[i]=read(),v[i]=read();insert(u[i],v[i]);insert(v[i],u[i]);}tarjan(1,0);memset(first,tot=0,sizeof(first));for(int i=1;i<=m;i++)if(bel[u[i]]^bel[v[i]]){insert(bel[u[i]],bel[v[i]]);insert(bel[v[i]],bel[u[i]]);}dfs(1);for(int j=1,q=log2(n);j<q;j++)for(int i=1;i<=n;i++){f[i][j]=f[f[i][j-1]][j-1];g[i][j]=g[i][j-1]+g[f[i][j-1]][j-1];}for(int i=p[0]=1;i<=n;i++) p[i]=p[i-1]*2%mo;int q=read();while(q--) write(p[lca(bel[read()],bel[read()])]),putchar('\n');return 0; }總結(jié)
以上是生活随笔為你收集整理的JZOJ 5305. 【NOIP2017提高A组模拟8.18】C的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 5286. 【NOIP2017
- 下一篇: 5334. 【NOIP2017提高A组模