求桥
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
const int maxm = 4e5 + 10;
struct egde{ int v, nxt; }Edge[maxm];
int Head[maxn], cnt;
int LOW[maxn], DFN[maxn], Fa[maxn], INDEX;
int N, M;
struct no
{
int u,v;
}BG[maxm];
bool cmp(no a , no b)
{
if(a.u!=b.u)
return a.u<b.u;
return a.v<b.v;
}
void init()
{
for(int i=0; i<=N; i++)
Head[i] = LOW[i] = DFN[i] = -1, Fa[i] = 0;
cnt = INDEX = 0;
}
inline void AddEdge(int from, int to)
{
Edge[cnt].v = to;
Edge[cnt].nxt = Head[from];
Head[from] = cnt++;
}
void Tarjan(int v, int Father)
{
Fa[v] = Father;
DFN[v] = LOW[v] = INDEX++;
for(int i=Head[v]; i!=-1; i=Edge[i].nxt){
int Eiv = Edge[i].v;
if(DFN[Eiv] == -1){
Tarjan(Eiv, v);
LOW[v] = min(LOW[v], LOW[Eiv]);
}
else if(Father != Eiv)
LOW[v] = min(LOW[v], DFN[Eiv]);
}
}
void solve()
{
int ans = 0;
Tarjan(0, -1);
for(int i=0; i<N; i++){
int v = Fa[i];
if(v >= 0 && LOW[i] > DFN[v]){//满足是桥的条件
// v->i is bridge
BG[ans].u=min(v,i);//贮存
BG[ans++].v = max(v,i);
}
}
sort(BG, BG+ans,cmp);
printf("%d
", ans);
if(ans > 0){
for(int i=0; i<ans; i++)
printf("%d %d
", BG[i].u, BG[i].v);
}puts("");
}
int main(void)
{
while(~scanf("%d %d", &N, &M)){
init();
int from, to;
while(M--){
scanf("%d %d", &from, &to);
AddEdge(from, to);
AddEdge(to, from);
}
solve();
}
return 0;
}
求割点
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
const int maxm = 4e5 + 10;
struct no{ int v, nxt; }Edge[maxm];
int head[maxn], cnt;
int low[maxn], DFN[maxn], Fa[maxn], INDEX;
int is_cut[maxn];
int N, M;
inline void init()
{
for(int i=0; i<=N; i++)
head[i] = low[i] = DFN[i] = Fa[i] = -1,
is_cut[i] = false;
cnt = INDEX = 0;
}
inline void AddEdge(int from, int to)
{
Edge[cnt].v = to;
Edge[cnt].nxt = head[from];
head[from] = cnt++;
}
void Tarjan(int v, int Father)
{
Fa[v] = Father;
DFN[v] = low[v] = INDEX++;
for(int i=head[v]; i!=-1; i=Edge[i].nxt){
int Eiv = Edge[i].v;
if(DFN[Eiv] == -1){
Tarjan(Eiv, v);
low[v] = min(low[v], low[Eiv]);
}
else if(Father != Eiv)
low[v] = min(low[v], low[Eiv]);
}
}
void solve()
{
int Cut_Num = 0;
int Root_Child = 0;
Tarjan(0, -1);
for(int i=1; i<N; i++){
int v = Fa[i];
if(v == 0) Root_Child++;
else if(low[i] >= DFN[v] && !is_cut[v]) is_cut[v] = true, Cut_Num++;
}
if(Root_Child > 1) is_cut[0] = true, Cut_Num++;
//求桥
// for(int i=0; i<n; i++){
// int v = Fa[i];
// if(v >= 0 && low[i] > DFN[v])
// // v->i is bridge
// }
///-----------------求割点
printf("%d
", Cut_Num);
if(Cut_Num != 0){
for(int i=0; i<N; i++)
if(is_cut[i])
printf("%d ", i);
puts("");
}puts("");
///-----------------
}
int main(void)
{
while(~scanf("%d %d", &N, &M)){
init();
int from, to;
while(M--){
scanf("%d %d", &from, &to);
AddEdge(from, to);
AddEdge(to, from);
}
solve();
}
return 0;
}