您的位置:首页 > 其它

poj 3694 Network

2013-11-01 20:24 330 查看
分析:先缩点成树,然后模拟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]);
//        }
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: