【一只蒟蒻的刷题历程】--- 【洛谷】 P1656 炸铁路 (Tarjan算法 割边模板题)

一只蒟蒻的第一篇博客。。。

记录自己的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;   //愉快的水完一题
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值