[bzoj3331] [BeiJing2013] 压力(tarjan 点双连通分量)

匿名 (未验证) 提交于 2019-12-02 23:48:02



 1         if(!dfn[to]){  2             tarjan(to);  3             low[x]=min(low[x],low[to]);  4             if(low[to]>=dfn[x]){  5                 opt++; sum++;  6                 if(x!=1||opt>1) cut[x]=1;  7                 do{  8                     tmp=sta[up--];  9                     cir[tmp]=sum; 10                     dcc[sum].push_back(tmp); 11                 }while(tmp!=to); 12                 cir[x]=sum; 13                 dcc[sum].push_back(x); 14             } 15         } 16         else low[x]=min(low[x],dfn[to]);    

 1 #include<cstdio>  2 #include<cstring>  3 #include<queue>  4 #include<iostream>  5 #define $ 220010  6 using namespace std;  7 int m,n,q,first[$],tot1,dfn[$],low[$],tar,tip[$],second[$],tot2;  8 int dad[$][22],sta[$],up,ans[$],dep[$],sum,pre[$];  9 struct tree{    int to,next;    }a[$*5],tr[$*5]; 10 inline int min(int x,int y)    {    return x<y?x:y;    } 11 inline void swap(int &x,int &y){    int t=x; x=y; y=t;    } 12 inline void add(int x,int y){     13     a[++tot1]=(tree){    y,first[x]    }; 14     first[x]=tot1; 15     a[++tot1]=(tree){    x,first[y]    }; 16     first[y]=tot1; 17 } 18 inline void addtr(int x,int y){ 19     tr[++tot2]=(tree){    y,second[x]    }; 20     second[x]=tot2; 21     tr[++tot2]=(tree){    x,second[y]    }; 22     second[y]=tot2; 23 } 24 inline void tarjan(int x){ 25     dfn[x]=low[x]=++tar;  sta[++up]=x; 26     for(register int i=first[x],tmp;i;i=a[i].next){ 27         int to=a[i].to; 28         if(!dfn[to]){ 29             tarjan(to); 30             low[x]=min(low[x],low[to]); 31             if(low[to]>=dfn[x]){ 32                 ++sum; 33                 do{ 34                     tmp=sta[up--]; 35                     addtr(sum,tmp); 36                 }while(tmp!=to); 37                 addtr(sum,x); 38             } 39         } 40         else low[x]=min(low[x],dfn[to]); 41     } 42 } 43 inline void ready(int x){ 44     pre[--pre[0]]=x; 45     for(register int i=second[x];i;i=tr[i].next){ 46         int to=tr[i].to; 47         if(to==dad[x][0]) continue; 48         dad[to][0]=x; 49         for(register int j=1;j<=20;++j) dad[to][j]=dad[dad[to][j-1]][j-1]; 50         dep[to]=dep[x]+1; 51         ready(to); 52     } 53 } 54 inline int LCA(int x,int y){ 55     if(dep[x]<dep[y]) swap(x,y); 56     for(register int i=20;i>=0;--i) 57         if(dep[dad[x][i]]>=dep[y]) x=dad[x][i]; 58     if(x==y) return x; 59     for(register int i=20;i>=0;--i) 60         if(dad[x][i]!=dad[y][i]) x=dad[x][i],y=dad[y][i]; 61     return dad[x][0]; 62 } 63 signed main(){ 64     scanf("%d%d%d",&n,&m,&q); sum=n; 65     for(register int i=1,x,y;i<=m;++i) scanf("%d%d",&x,&y),add(x,y); 66     tarjan(1); 67     pre[0]=sum+1; dep[1]=1; 68     ready(1); 69     for(register int i=1,x,y,lca;i<=q;++i){ 70         scanf("%d%d",&x,&y);  lca=LCA(x,y); 71         ++ans[x];   ++ans[y]; 72         --ans[lca]; --ans[dad[lca][0]]; 73     } 74     for(register int i=1,x;i<=sum;++i) 75          x=pre[i],ans[dad[x][0]]+=ans[x]; 76     for(register int i=1;i<=n;++i) printf("%d\n",ans[i]); 77 }
View Code

 1 #include<cstdio>  2 #include<cstring>  3 #include<queue>  4 #include<vector>  5 #define $ 220010  6 using namespace std;  7 int m,n,q,first[$],tot1,dfn[$],low[$],tar,tip[$],second[$],tot2,cut[$],cnt;  8 int dad[$*2][22],sta[$],up,ans[$],dep[$],sum,pre[$],cir[$],id[$],data[$];  9 vector<int> dcc[$]; 10 struct tree{    int to,next;    }a[$*5],tr[$*5]; 11 inline int min(int x,int y)    {    return x<y?x:y;    } 12 inline void swap(int &x,int &y){    int t=x; x=y; y=t;    } 13 inline void add(int x,int y){     14     a[++tot1]=(tree){    y,first[x]    }; 15     first[x]=tot1; 16     a[++tot1]=(tree){    x,first[y]    }; 17     first[y]=tot1; 18 } 19 inline void addtr(int x,int y){ 20     tr[++tot2]=(tree){    y,second[x]    }; 21     second[x]=tot2; 22     tr[++tot2]=(tree){    x,second[y]    }; 23     second[y]=tot2; 24 } 25 inline void tarjan(int x,int opt=0){ 26     dfn[x]=low[x]=++tar;  sta[++up]=x; 27     for(register int i=first[x],tmp;i;i=a[i].next){ 28         int to=a[i].to; 29         if(!dfn[to]){ 30             tarjan(to); 31             low[x]=min(low[x],low[to]); 32             if(low[to]>=dfn[x]){ 33                 opt++; sum++; 34                 if(x!=1||opt>1) cut[x]=1; 35                 do{ 36                     tmp=sta[up--]; 37                     cir[tmp]=sum; 38                     dcc[sum].push_back(tmp); 39                 }while(tmp!=to); 40                 cir[x]=sum; 41                 dcc[sum].push_back(x); 42             } 43         } 44         else low[x]=min(low[x],dfn[to]); 45     } 46 } 47 inline void ready(int x){ 48     pre[--pre[0]]=x; 49     for(register int i=second[x];i;i=tr[i].next){ 50         int to=tr[i].to; 51         if(to==dad[x][0]) continue; 52         dad[to][0]=x; 53         for(register int j=1;j<=20;++j) dad[to][j]=dad[dad[to][j-1]][j-1]; 54         dep[to]=dep[x]+1; 55         ready(to); 56     } 57 } 58 inline int LCA(int x,int y){ 59     if(dep[x]<dep[y]) swap(x,y); 60     for(register int i=20;i>=0;--i) 61         if(dep[dad[x][i]]>=dep[y]) x=dad[x][i]; 62     if(x==y) return x; 63     for(register int i=20;i>=0;--i) 64         if(dad[x][i]!=dad[y][i]) x=dad[x][i],y=dad[y][i]; 65     return dad[x][0]; 66 } 67 signed main(){ 68     scanf("%d%d%d",&n,&m,&q); cnt=n; 69     for(register int i=1,x,y;i<=m;++i) scanf("%d%d",&x,&y),add(x,y); 70     tarjan(1); 71     for(register int i=1;i<=n;++i) if(cut[i]) cir[i]=id[i]=++cnt; 72     for(register int i=1;i<=sum;++i) 73         for(register int j=0;j<dcc[i].size();++j){ 74             int to=dcc[i][j]; 75             if(cut[to]) addtr(i,id[to]); 76         } 77     pre[0]=cnt+1; dep[1]=1; 78     ready(1); 79     for(register int i=1,x,y,lca;i<=q;++i){ 80         scanf("%d%d",&x,&y);   81         if(!cut[x]) data[x]++; 82         if(!cut[y]) data[y]++; 83         x=cir[x], y=cir[y];  84         lca=LCA(x,y); 85         ++ans[x];   ++ans[y]; 86         --ans[lca]; --ans[dad[lca][0]]; 87     } 88     for(register int i=1,x;i<=cnt;++i) 89          x=pre[i],ans[dad[x][0]]+=ans[x]; 90     for(register int i=1;i<=n;++i) printf("%d\n",cut[i]?ans[cir[i]]:data[i]); 91 }
View Code

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!