hdu 4612 无向图连通分量缩点,然后求树的最大直径
#pragma comment(linker,"/STACK:102400000,102400000")
#include <iostream>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 200100;
const int maxm = 2000100;
struct node{
int v,next;
}edge[maxm];
struct Bridge
{
int u,v;
}bridge[maxm];
int head[maxn],vis[maxm],fa[maxn],dfn[maxn],low[maxn],stack[maxn],in[maxn];
int id,time,num,total,top,ans;
void add_edge(int u,int v)
{
edge[id].v = v;edge[id].next = head[u],head[u] = id++;
edge[id].v = u;edge[id].next = head[v],head[v] = id++;
}
int min(int x,int y)
{
return x < y ? x : y;
}
void tarjan(int u)
{//无向图找桥并缩点
low[u] = dfn[u] = ++time;
stack[top++] = u;
for(int id = head[u] ; id != -1; id = edge[id].next)
{
int v =edge[id].v;
if(vis[id])continue;
vis[id] = vis[id^1] = 1;
if( !dfn[v] )
{
tarjan(v);
low[u] = min(low[u],low[v]);
if( low[v] > dfn[u])//u经过v不能回到u,则u与v之间存在桥
{
bridge[total].u = u;
bridge[total++].v = v;
}
}
low[u] = min(low[u],dfn[v]);
}
if(low[u] == dfn[u])
{//对连通分量进行缩点
num++;
int t;
do{
t = stack[--top];
fa[t] = num;
}while( t != u);
}
}
vector<int>g[maxn]; int dfs(int u)
{//求树的最大直径
vis[u]=1;
int i,j,temp=0,Max=0,lMax=0;//Max为以u为根,u到的最远的叶子节点的距离,lMax为次最远距离
for(i = 0; i < g[u].size() ; i++ ){
int v = g[u][i];
if(vis[v])continue;
temp=dfs(v);
if(temp+1>=Max){
lMax=Max;
Max=temp+1;
}
else
if(temp+1>lMax)
lMax=temp+1;
if(Max+lMax>ans)
ans=Max+lMax;
}
return Max;
} int max_len()
{//求树的最大直径
int res = 0;
memset(vis,0,sizeof(vis));
queue<int>que;
que.push(1);
vis[1] = 1;
int tmp;
while( !que.empty())
{
int u = que.front();
que.pop();
tmp = u;
for( int i = 0 ; i < g[u].size(); i++)
{
int v = g[u][i];
if( vis[v] )continue;
vis[v] = 1;
que.push(v);
}
} queue<pair<int,int> >que1;
memset(vis,0,sizeof(vis));
que1.push(make_pair(tmp,0));
pair<int,int>x,y;
vis[tmp] = 1;
while( !que1.empty())
{
x = que1.front();
que1.pop();
for(int i = 0; i < g[x.first].size() ; i++)
{
int v = g[x.first][i];
if( vis[v] )continue;
vis[v] = 1;
que1.push(make_pair(v,x.second+1));
res = res > x.second ? res : x.second + 1;
}
}
return res;
}
int main()
{
int n,m,u,v;
int i;
// freopen("in.txt","r",stdin);
while( ~scanf("%d%d",&n,&m) && n+m)
{
id = 0;
memset(head,-1,sizeof(head));
while( m-- )
{
scanf("%d%d",&u,&v);
add_edge(u,v);
}
total = num = 0;
memset(dfn,0,sizeof(dfn));
memset(fa,-1,sizeof(fa));
memset(vis,0,sizeof(vis));
for(i = 1; i <= n; i++)//可以处理不连通的无向图,如果连通只需要一次即可
{
if( !dfn[i] )
{
top = time = 1;
tarjan(i);
//num++;
//for( int j = 1; j <= n; j++) //特殊处理顶点的连通块
// if( dfn[j] && fa[j] == -1)fa[j] = num;
}
}
//for( i = 1; i <= n; i++)cout << fa[i] << endl;
for(i = 1; i <= n;i++)g[i].clear();
int x,y;
//建树
// cout << total << endl;
for( i = 0 ; i < total; i++)
{
x = fa[bridge[i].u];
y = fa[bridge[i].v];
//cout << x << " " << y << endl;
g[x].push_back(y);
g[y].push_back(x);
}
memset(vis,0,sizeof(vis));
ans = 0;
dfs(1);
printf("%d\n",total - ans );
}
return 0;
}
hdu 4612 无向图连通分量缩点,然后求树的最大直径的更多相关文章
- hdu 4612 双联通缩点+树形dp
#pragma comment(linker,"/STACK:102400000,102400000")//总是爆栈加上这个就么么哒了 #include<stdio.h> ...
- HDU-4612 Warm up,tarjan求桥缩点再求树的直径!注意重边
Warm up 虽然网上题解这么多,感觉写下来并不是跟别人竞争访问量的,而是证明自己从前努力过,以后回头复习参考! 题意:n个点由m条无向边连接,求加一条边后桥的最少数量. 思路:如标题,tarjan ...
- HDU4612+Tarjan缩点+BFS求树的直径
tarjan+缩点+树的直径题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少.先tarjan缩点,再在这棵树上求直径.加的边即是连接这条直径的两端. /* tarjan ...
- HDU 4607 Park Visit 两次DFS求树直径
两次DFS求树直径方法见 这里. 这里的直径是指最长链包含的节点个数,而上一题是指最长链的路径权值之和,注意区分. K <= R: ans = K − 1; K > R: ans = ...
- HDU 4607 Park Visit 树的最大直径
题意: 莱克尔和她的朋友到公园玩,公园很大也很漂亮.公园包含n个景点通过n-1条边相连.克莱尔太累了,所以不能去参观所有点景点. 经过深思熟虑,她决定只访问其中的k个景点.她拿出地图发现所有景点的入口 ...
- HDU 4612 Warm up(双连通分量缩点+求树的直径)
思路:强连通分量缩点,建立一颗新的树,然后求树的最长直径,然后加上一条边能够去掉的桥数,就是直径的长度. 树的直径长度的求法:两次bfs可以求,第一次随便找一个点u,然后进行bfs搜到的最后一个点v, ...
- hdoj 4612 Warm up【双连通分量求桥&&缩点建新图求树的直径】
Warm up Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Su ...
- HDU 4612 Warm up (边双连通分量+缩点+树的直径)
<题目链接> 题目大意:给出一个连通图,问你在这个连通图上加一条边,使该连通图的桥的数量最小,输出最少的桥的数量. 解题分析: 首先,通过Tarjan缩点,将该图缩成一颗树,树上的每个节点 ...
- HDU 4612——Warm up——————【边双连通分量、树的直径】
Warm up Time Limit:5000MS Memory Limit:65535KB 64bit IO Format:%I64d & %I64u Submit Stat ...
随机推荐
- xml的四种解析方式(转载)
众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J 下面首先给出这四种方法的jar包下载地址 DOM:在现在的Java JDK里都自带了,在xml- ...
- 改 Anaconda Jupyter Notebook 开发文件保存目录
1.打开cmd,输入命令找到配置文件路径 jupyter notebook --generate-config 2.打开 jupyter_notebook_config.py 修改配置 c.Noteb ...
- 一文速览Vue全栈
一文速览Vue全栈 原创: 新哥Lewis 天道酬勤Lewis 7月7日 Vue 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用,专注于声明式渲染视图 ...
- 微信公众号发送消息给用户 php
1.微信公众号 这里得话 一开始先去看了 微信公众号的接口 发现网页授权需要时认证的服务号,一开始想的是那去申请一个认证的服务号岂不是很费事,然后网上搜了搜,发现了还有微信公众号个人测试号这个东西,所 ...
- 线性分类 Linear Classification
软分类:y 的取值只有正负两个离散值,例如 {0, 1} 硬分类:y 是正负两类区间中的连续值,例如 [0, 1] 一.感知机 主要思想:分错的样本数越少越好 用指示函数统计分错的样本数作为损失函数, ...
- 单机版ZooKeeper的安装教程
之前一直没有时间去整理,现在抽出几分钟时间整理以下,有问题的在评论区留言即可. 前期准备JDK环境(ZK需要jdk进行编译,本文以jdk1.8.0_211为例).Linux系统(本文以Centos7为 ...
- JSP前端数据本地排序
在前端中我们经常需要数据的排序,首先写引入我写好的js $(function($) { $('#sclazzId').val($('#voId').val()); document.getElemen ...
- 某团面试题:JVM 堆内存溢出后,其他线程是否可继续工作?
转载注明:http://dwz.win/gHc 最近网上出现一个美团面试题:"一个线程OOM后,其他线程还能运行吗?".我看网上出现了很多不靠谱的答案.这道题其实很有难度,涉及的知 ...
- net core Webapi基础工程搭建(六)——数据库操作_Part 1
目录 前言 SqlSugar Service层 BaseService(基类) 小结 前言 后端开发最常打交道的就是数据库了(静态网站靠边),上一篇net core Webapi基础工程搭建(五)-- ...
- linux常用命令示例汇总
1.ping -c 3 -i 0.1 -W 1 -t 3 100.100.242.181 -c发包数目,-c 3三个 -i,发包间隔,-i 0.1,每隔0.1秒发一个包 -W,发包超时时间,-W 1, ...