一只蒟蒻的第一篇博客。。。
记录自己的coding life。。。
话不多说,代码附上,个人认为注释比较清晰,应该很好理解。。。。
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
using namespace std;
struct node{
int u;
int v;
node(){}
node(int a,int b){u=a;v=b;}
friend bool operator <(node a,node b)
{
if(a.u!=b.u) return a.u>b.u; //重载运算符<符号,所以return ?>?时升序排列(从小到大)
else return a.v>b.v;
}
};
priority_queue<node> q; //个人喜欢用这方法排出答案,也可以使用pair,map啥的,或者结构体+cmp
const int maxn=160;
int n,m,a,b,low[maxn],dfn[maxn],cnt=0; //cnt为时间戳
vector<int> g[maxn]; //用邻接表储存
void cut(int u,int father)
{
low[u]=dfn[u]=++cnt; //每个点初始时间戳
for(int i=0;i<g[u].size();i++)
{
int v=g[u][i];
if(dfn[v] && v!=father) //儿子v访问过,并且不是根
low[u]=min(low[u],dfn[v]); //即可能到达父u的祖先,于是更新u的low值
if(!dfn[v])
{
cut(v,u); //儿子v没访问过,dfs
low[u]=min(low[u],low[v]); /*回溯更新u值,因为儿子v可能到过u的祖先而更新low值。
由于父亲能连接儿子,同时父亲可能是其他点的儿子,
所以更新父亲能到的low值 (个人理解)*/
if(dfn[u] < low[v])
q.push(node(u,v)); //如果是割边,放入队列
}
}
}
int main()
{
cin>>n>>m;
while(m--)
{
cin>>a>>b;
g[a].push_back(b); //存图
g[b].push_back(a);
}
for(int i=1;i<=n;i++) //图可能不是连通图,所以一次循环
if(!dfn[i]) cut(i,i); //可能没有走过另一个连通块,因而遍历一遍
while(!q.empty()) //输出答案
{
cout<<q.top().u<<" "<<q.top().v<<endl;
q.pop();
}
return 0; //愉快的水完一题
}