求割点

来源:互联网 发布:阿玛拉王国 mac 下载 编辑:程序博客网 时间:2024/06/07 04:01

DFS求割点,用2个数组来记录搜索的信息,DFN记录为访问的时间,L[ ]记录能回到的最小祖节点 最后比较这两个数组的大小,来判断这个点是不是割点

 /*

10 13
1 2
1 4
3 4
2 3
3 10
3 9
6 5
2 5
2 7
2 8
5 8
5 7
7 8
*/
#include<bits/stdc++.h>
using namespace std;
int DFN[100];
int L[100];
int num=1,n;
struct Edge{
int to;
};
vector<Edge> e[100];
void Try(int u,int v)
{
DFN[u]=num;
L[u]=num;
num++;
for(int i=0;i<e[u].size();i++)
{
if(DFN[e[u][i].to]==0)//如果这个点没有访问过,就进行访问 
{
Try(e[u][i].to,u);
if(L[u]>L[e[u][i].to])//搜索结束后,L[u]表示U节点及其子节点最低能到达的祖节点 
L[u]=L[e[u][i].to];
}
else if(e[u][i].to!=v)
{
if(L[u]>DFN[e[u][i].to])//如果回到的节点大于自己,那么就标记自己 
L[u]=DFN[e[u][i].to];
}

}
}
int main()
{
memset(L,0,sizeof(L));
memset(DFN,0,sizeof(DFN));
freopen("GeDian.txt","r",stdin);
int m;
cin>>n>>m;
for(int i=0;i<m;i++)
{
int a,b;
cin>>a>>b;
Edge tmp;
tmp.to=b;
e[a].push_back(tmp);
tmp.to=a;
e[b].push_back(tmp);
}
for(int i=1;i<=n;i++)
{
cout<<i<<": ";
for(int j=0;j<e[i].size();j++)
cout<<e[i][j].to<<" "; 
cout<<endl;
}
Try(1,1);
for(int i=1;i<=10;i++)
cout<<L[i]<<" ";
cout<<endl; 
for(int i=1;i<=10;i++)
cout<<DFN[i]<<" ";
cout<<endl; 

for(int i=1;i<=n;i++)
{
int flag=0;
for(int j=0;j<e[i].size();j++)
{
if(L[e[i][j].to]>=DFN[i])//儿子返回的祖节点比本身还有大 说明自己是个割点 
{
flag=1;
}
}
if(flag)
cout<<i<<" ";
}
cout<<endl;
}
0 0