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 ...
随机推荐
- BME200加密网关,在电力与工业应用的加密网关设计与介绍
加密通信网关,顾名思义就是带加密的通信网关终端, 一般业内主是需用到是工业通信关行业的为主的.,BME200加密通信网关,主要电力和工业互联网相关领域开发的一款加密通信网关. 为什么出现加密网关 1 ...
- Golang版本的rocksdb-对gorocksdb的封装
rocksdb的优秀特性不用多说,但是它是用c++语言写的,就是这一个特点就把很多人拦住了.虽然rocksdb官方也有Java版本,但是Golang的发展速度让人不容小觑,而且由于golang原生对高 ...
- Where is the clone one and how to extract it?
One cannot be in two places at once. Do you know what's "Dual Apps"? Manufactures like Xia ...
- Java----面向对象(继承&多态)
一.继承 什么是继承 ? 让类与类之间产生了子父类关系 ; 继承的好处是: 提高代码的复用性和维护性 java中继承的特点是: 只支持单继承.不支持多继承,但是可以多层继承; 四种权限修饰符是 : p ...
- c#将字符串转化为合理的文件名
string name = System.Text.RegularExpressions.Regex.Replace(url, "[<>/\\|:\"?*]" ...
- 关于dfs的套路
void dfs(答案, 搜索层数, 其他参数) { if (层数==maxdeep) { 更新答案 return; } (剪枝) for(下一层可能的状态){ 更新全局变量表示的状态的变量 dfs( ...
- javaweb基础整理随笔------jstl与el表达式
虽然jsp中可以写java代码,但是现在不推荐这么做. jsp虽然本质是servlet,但是主要作用只是视图,视图的任务就是显示响应,而不是在JSP中做任何关于程序控制和业务逻辑的事情.所以在JSP页 ...
- android ——Toolbar
Toolbar是我看material design内容的第一个 官方文档:https://developer.android.com/reference/android/support/v7/widg ...
- Knative 基本功能深入剖析:Knative Serving 之服务路由管理
导读:本文主要围绕 Knative Service 域名展开,介绍了 Knative Service 的路由管理.文章首先介绍了如何修改默认主域名,紧接着深入一层介绍了如何添加自定义域名以及如何根据 ...
- 如何使用Python连接ldap
如何使用Python连接ldap 好多使用ldap认证的软件都是Python的,比如superset和airflow, 好吧,他们都是airbnb家的.在配置ldap的时候可能会出现认证失败,你不知道 ...