poj 3694 求割边+LCA
2015-07-27 16:04
405 查看
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;
#define N 100100
vector<int>v
;
bool isbridge
;
int vis
,dfn
,low
,fa
;int ans,index;
void LCA(int x,int y)
{
while(dfn[y]<dfn[x])
{
if(isbridge[x])
isbridge[x]=0,ans--;
x=fa[x];
}
while(dfn[x]<dfn[y])
{
if(isbridge[y])
isbridge[y]=0,ans--;
y=fa[y];
}
while(x!=y)
{
if(isbridge[x])isbridge[x]=0,ans--;
if(isbridge[y])isbridge[y]=0,ans--;
x=fa[x];
y=fa[y];
}
}
void tarjan(int x)
{
int y;
low[x]=dfn[x]=++index;
vis[x]=1;
for(int i=0;i<v[x].size();i++)
{
y=v[x][i];
if(y!=fa[x])
{
if(vis[y]==1)//儿子节点还在栈中,就与儿子节点比较;
low[x]=min(dfn[y],low[x]);
else if(vis[y]==0)//或者是dfn[x]==0;两者是一样的,表示还未没搜索过;
{
fa[y]=x;
tarjan(y);
low[x]=min(low[x],low[y]); //更新当前节点
if(dfn[x]<low[y])//表示边x-y是桥;
{
isbridge[y]=1;
ans++;
}
}
}
}
vis[x]=2;
return ;
}
int main()
{
int n,m,k,a,b;int q=1;
while(cin>>n>>m)
{
if(n==0&&m==0)
break;
for(int i=1;i<=n;i++)
v[i].clear();
for(int i=0;i<m;i++)
{
scanf("%d %d",&a,&b);
v[a].push_back(b);
v[b].push_back(a);
}
cin>>k;
index=0;ans=0;
memset(vis,0,sizeof(vis));
memset(fa,0,sizeof(fa));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(isbridge,0,sizeof(isbridge));
tarjan(1);
// for(int i=1;i<=n;i++)
// cout<<low[i]<<" ";
// cout<<endl;
cout<<"Case "<<q++<<":"<<endl;
while(k--)
{
scanf("%d %d",&a,&b);
LCA(a,b);
cout<<ans<<endl;
}
}
return 0;
}
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
using namespace std;
#define N 100100
vector<int>v
;
bool isbridge
;
int vis
,dfn
,low
,fa
;int ans,index;
void LCA(int x,int y)
{
while(dfn[y]<dfn[x])
{
if(isbridge[x])
isbridge[x]=0,ans--;
x=fa[x];
}
while(dfn[x]<dfn[y])
{
if(isbridge[y])
isbridge[y]=0,ans--;
y=fa[y];
}
while(x!=y)
{
if(isbridge[x])isbridge[x]=0,ans--;
if(isbridge[y])isbridge[y]=0,ans--;
x=fa[x];
y=fa[y];
}
}
void tarjan(int x)
{
int y;
low[x]=dfn[x]=++index;
vis[x]=1;
for(int i=0;i<v[x].size();i++)
{
y=v[x][i];
if(y!=fa[x])
{
if(vis[y]==1)//儿子节点还在栈中,就与儿子节点比较;
low[x]=min(dfn[y],low[x]);
else if(vis[y]==0)//或者是dfn[x]==0;两者是一样的,表示还未没搜索过;
{
fa[y]=x;
tarjan(y);
low[x]=min(low[x],low[y]); //更新当前节点
if(dfn[x]<low[y])//表示边x-y是桥;
{
isbridge[y]=1;
ans++;
}
}
}
}
vis[x]=2;
return ;
}
int main()
{
int n,m,k,a,b;int q=1;
while(cin>>n>>m)
{
if(n==0&&m==0)
break;
for(int i=1;i<=n;i++)
v[i].clear();
for(int i=0;i<m;i++)
{
scanf("%d %d",&a,&b);
v[a].push_back(b);
v[b].push_back(a);
}
cin>>k;
index=0;ans=0;
memset(vis,0,sizeof(vis));
memset(fa,0,sizeof(fa));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(isbridge,0,sizeof(isbridge));
tarjan(1);
// for(int i=1;i<=n;i++)
// cout<<low[i]<<" ";
// cout<<endl;
cout<<"Case "<<q++<<":"<<endl;
while(k--)
{
scanf("%d %d",&a,&b);
LCA(a,b);
cout<<ans<<endl;
}
}
return 0;
}
相关文章推荐
- 两个数值互换的三种算法
- What is Observer and Observable and when we used these?
- windows service 的创建 安装 调试 错误回发
- Lua与C++ 第五篇(C++调用Lua的函数)
- PHP AJAX JSONP实现跨域请求使用实例
- js学习总结
- python-re模块-使用案例
- JQUERY实现网页右下角固定位置展开关闭特效的方法
- 某电商网站线上drbd+heartbeat+nfs配置
- 【JavaScript】数据类型
- HDU 5312-Sequence(三角形数+推导)
- Patch
- 最少拦截系统 SDUToj 2075
- 关于cocos2dx 3.x自适配屏幕
- 【HDU】5307 He is Flying【分别统计+NTT】
- ORACLE数据迁移
- hdu 1002 A + B Problem II
- Scala练习(四)
- Scala练习(五)
- js与后台交互详述(入门篇)