poj 3694 Network
来源:互联网 发布:excel圆环图数据标志 编辑:程序博客网 时间:2024/05/18 03:03
分析:先缩点成树,然后模拟LCA过程。
#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;const int maxn = 200500;//const int maxm = 405000;struct Node{ int v,next;}e[maxn*4],tree[maxn*4];int bridge,vis[maxn],pre[maxn],head[maxn];int dfn[maxn],low[maxn],head1[maxn],id[maxn],index,top,num,scc,sta[maxn];void add(int a,int b){ e[num].v=b; e[num].next=head[a]; head[a]=num++;}void add_tree(int a,int b){ tree[num].v=b; tree[num].next=head1[a]; head1[a]=num++;}void init(){ top=0; scc=num=index=0; memset(dfn,0,sizeof(dfn));}void tarjan(int u,int fa){ dfn[u]=low[u]=++index; sta[++top]=u; int cnt=0; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; if(!dfn[v]){ tarjan(v,u); low[u]=min(low[u],low[v]); } else if(fa==v){ if(cnt) low[u]=min(low[u],dfn[v]); cnt++; } else{ low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]){ int x; scc++; do{ x=sta[top--]; id[x]=scc; // printf("%d ",x); }while(x!=u); // printf("\n"); }}int ran[maxn];void lca_dfs(int u,int dept,int fa){ ran[u]=dept; for(int i=head1[u];i!=-1;i=tree[i].next){ int v=tree[i].v; if(v==fa) continue; low[v]=1; lca_dfs(v,dept+1,u); pre[v]=u; }}void lca(int u,int v){ while(ran[u]>ran[v]){ if(low[u]){ low[u]=0; bridge--; } u=pre[u]; } while(ran[u]<ran[v]){ if(low[v]){ low[v]=0; bridge--; } v=pre[v]; } while(u!=v){ if(low[u]){ bridge--; low[u]=0; } if(low[v]){ bridge--; low[v]=0; } u=pre[u]; v=pre[v]; }}int main(){ int n,m,con=1; while(~scanf("%d %d",&n,&m) && (n+m)){ init(); for(int i=0;i<=n;i++){ head[i]=-1; vis[i]=0; } for(int i=0;i<m;i++){ int a,b; scanf("%d %d",&a,&b); add(a,b); add(b,a); } for(int i=1;i<=n;i++){ if(!dfn[i]){ tarjan(i,-1); } } num=0; for(int i=0;i<=n;i++){ head1[i]=-1; low[i]=0; } for(int u=1;u<=n;u++){ // vis[u]=1; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].v; // if(vis[v]) continue; if(id[u]!=id[v]){ add_tree(id[u],id[v]); // printf("link----%d %d\n",id[u],id[v]); } } } lca_dfs(1,1,-1); bridge=scc-1;// for(int i=1;i<=scc;i++){// printf("%d---%d\n",i,ran[i]);// } int q; scanf("%d",&q); printf("Case %d:\n",con++); while(q--){ int a,b; scanf("%d %d",&a,&b); if(id[a]!=id[b]){ lca(id[a],id[b]); } // else{ printf("%d\n",bridge); // } } // printf("%d\n",bridge);// for(int i=1;i<=n;i++){// printf("%d---%d\n",i,id[i]);// } }}
- POJ 3694 Network
- poj 3694 Network
- POJ 3694 Network
- poj 3694 Network
- poj 3694 Network
- POJ 3694 Network
- POJ 3694 Network
- poj 3694 Network
- POJ 3694 Network
- POJ 3694 Network
- Poj 3694 Network
- poj 3694 Network
- POJ 3694 Network
- poj 3694 Network
- POJ 3694 Network
- POJ 3694 Network
- poj 3694 Network
- POJ-3694 NetWork
- Ruby开发入门
- 用OPenGL实现 Bresenham画线算法
- Qt模块化笔记之sql——执行sql语句
- [LeetCode]Two Sum
- 解决win和ubuntu12.10下adb devices 无法检测android手机问题
- poj 3694 Network
- 用OpenGL实现 中点画圆法
- 斐波纳契数列
- preloader架构及流程图
- 计算机视觉、机器学习相关领域论文和源代码大集合--持续更新……
- (原)Win8 关机批处理脚本
- 关于今天老师讲的树的一些基本练习
- 黑马程序员_正则表达式
- 机器学习大家与资源