hdu4612

Warm up

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)

Total Submission(s): 3184    Accepted Submission(s): 720

Problem Description
  N planets are connected by M bidirectional channels that allow instant transportation. It's always possible to travel between any two planets through these channels.

  If we can isolate some planets from others by breaking only one channel , the channel is called a bridge of the transportation system.

People don't like to be isolated. So they ask what's the minimal number of bridges they can have if they decide to build a new channel.

  Note that there could be more than one channel between two planets.
 
Input
  The input contains multiple cases.

  Each case starts with two positive integers N and M , indicating the number of planets and the number of channels.

  (2<=N<=200000, 1<=M<=1000000)

  Next M lines each contains two positive integers A and B, indicating a channel between planet A and B in the system. Planets are numbered by 1..N.

  A line with two integers '0' terminates the input.
 
Output
  For each case, output the minimal number of bridges after building a new channel in a line.
 
Sample Input
4 4
1 2
1 3
1 4
2 3
0 0
 
Sample Output
0

题意:

给定一个联通图,问加入一条边后,最少还余下多少个割边

分析:先求强连通分量个数num,然后缩点形成一棵树,再求树的直径cnt,答案就是num-1-cnt;

程序:

#pragma comment(linker, "/STACK:10240000000000,10240000000000")
#include"stdio.h"
#include"string.h"
#include"stdlib.h"
#include"stack"
#include"iostream"
#define M 201009
#define inf 99999999
using namespace std;
stack<int>q;
struct st
{
int u,v,w,next;
}edge[M*10];
int head[M],use[M],t,dis[M][3],in[M],index,num,belong[M],dfn[M],low[M]; void init()
{
t=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
edge[t].u=u;
edge[t].v=v;
edge[t].w=w;
edge[t].next=head[u];
head[u]=t++;
}
void tarjan(int u,int id)
{
dfn[u]=low[u]=++index;
q.push(u);
use[u]=1;
int i;
for(i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(i==(id^1))continue;
if(!dfn[v])
{
tarjan(v,i);
low[u]=min(low[u],low[v]);
}
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
int vv;
num++;
do
{
vv=q.top();
q.pop();
belong[vv]=num;
use[vv]=0;
}while(vv!=u);
}
}
void dfs(int u)
{
use[u]=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v;
if(!use[v])
{
dfs(v);
//更新最大值和次大值
if(dis[u][0]<dis[v][0]+edge[i].w)
{
int tt=dis[u][0];
dis[u][0]=dis[v][0]+edge[i].w;
dis[u][1]=tt;
}
else if(dis[u][1]<dis[v][0]+edge[i].w)
dis[u][1]=dis[v][0]+edge[i].w;
}
}
if(in[u]==1&&u!=1)//注意
dis[u][0]=dis[u][1]=0;
}
void solve(int n)
{
index=num=0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(use,0,sizeof(use));
memset(belong,0,sizeof(belong));
tarjan(1,-1);
}
int uu[M],vv[M];
int main()
{
int n,m,i;
while(scanf("%d%d",&n,&m),m||n)
{
init();
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b,1);
add(b,a,1);
}
solve(n);
int cnt=0;
for(i=0;i<t;i+=2)
{
int u=edge[i].u;
int v=edge[i].v;
if(belong[u]!=belong[v])
{
uu[cnt]=belong[u];
vv[cnt]=belong[v];
cnt++;
}
}
init();
memset(in,0,sizeof(in));
memset(use,0,sizeof(use));
memset(dis,0,sizeof(dis));
for(i=0;i<cnt;i++)
{
//printf("%d %d\n",uu[i],vv[i]);
add(uu[i],vv[i],1);
add(vv[i],uu[i],1);
in[uu[i]]++;
in[vv[i]]++;
}
dfs(1);
int ans=0;
for(i=1;i<=num;i++)
{
if(ans<dis[i][0]+dis[i][1])
ans=dis[i][1]+dis[i][0];
}
printf("%d\n",num-1-ans);
}
return 0;
}

tarjan算法求缩点+树形DP求直径的更多相关文章

  1. 浅谈关于树形dp求树的直径问题

    在一个有n个节点,n-1条无向边的无向图中,求图中最远两个节点的距离,那么将这个图看做一棵无根树,要求的即是树的直径. 求树的直径主要有两种方法:树形dp和两次bfs/dfs,因为我太菜了不会写后者这 ...

  2. HDU 4514 - 湫湫系列故事——设计风景线 - [并查集判无向图环][树形DP求树的直径]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...

  3. 洛谷 P2515 [HAOI2010]软件安装(缩点+树形dp)

    题面 luogu 题解 缩点+树形dp 依赖关系可以看作有向边 因为有环,先缩点 缩点后,有可能图不联通. 我们可以新建一个结点连接每个联通块. 然后就是树形dp了 Code #include< ...

  4. hdu6446 网络赛 Tree and Permutation(树形dp求任意两点距离之和)题解

    题意:有一棵n个点的树,点之间用无向边相连.现把这棵树对应一个序列,这个序列任意两点的距离为这两点在树上的距离,显然,这样的序列有n!个,加入这是第i个序列,那么这个序列所提供的贡献值为:第一个点到其 ...

  5. 2017 Wuhan University Programming Contest (Online Round) B Color 树形dp求染色方法数

    /** 题目:Color 链接:https://oj.ejq.me/problem/23 题意:给定一颗树,将树上的点最多染成m种颜色,有些节点不可以染成某些颜色.相邻节点颜色不同.求染色方法数. 思 ...

  6. HDU - 3899 JLUCPC(树形dp求距离和)

    JLUCPC Dr. Skywind and Dr. Walkoncloud are planning to hold the annual JLU Collegiate Programming Co ...

  7. 洛谷P2515 [HAOI2010]软件安装(tarjan缩点+树形dp)

    传送门 我们可以把每一个$d$看做它的父亲,这样这个东西就构成了一个树形结构 问题是他有可能形成环,所以我们还需要一遍tarjan缩点 缩完点后从0向所有入度为零的点连边 然后再跑一下树形dp就行了 ...

  8. BZOJ 2427 /HAOI 2010 软件安装 tarjan缩点+树形DP

    终于是道中文题了.... 当时考试的时候就考的这道题.... 果断GG. 思路: 因为有可能存在依赖环,所以呢 先要tarjan一遍 来缩点. 随后就进行一遍树形DP就好了.. x表示当前的节点.j表 ...

  9. 树形DP求树的重心 --SGU 134

    令一个点的属性值为:去除这个点以及与这个点相连的所有边后得到的连通分量的节点数的最大值. 则树的重心定义为:一个点,这个点的属性值在所有点中是最小的. SGU 134 即要找出所有的重心,并且找出重心 ...

随机推荐

  1. dvi 中的内容居中

    text-align:right;  文本居中 line-height:35px;*垂直居中*

  2. 231个javascript特效分享

    1.文本框焦点问题onBlur:当失去输入焦点后产生该事件onFocus:当输入获得焦点后,产生该文件Onchange:当文字值改变时,产生该事件Onselect:当文字加亮后,产生该文件 <i ...

  3. activiti小结

    前提:业务流程复杂且流程频繁变更的,建议使用工作流:其他情况不建议使用. activiti(v5.14),工作流引擎,基于jbpm.使用建模语言BPMN2.0进行定义. 工作流数据需要写入数据库,ac ...

  4. 在不指定特殊属性的情况下,哪几种HTML标签可以手动输入文本:()

    A. <TEXTAREA></TEXTAREA> B. <INPUT type=”text”/> C. <INPUT type=”hidden”/> D ...

  5. The configuration file 'appsettings.json' was not found and is not optional

    问: .Net Core: Application startup exception: System.IO.FileNotFoundException: The configuration file ...

  6. 为什么要整合apache 和tomcat?

    1. Apache是web服务器,Tomcat是应用(java)服务器,它只是一个servlet容器,是Apache的扩展. 2. Apache和Tomcat都可以做为独立的web服务器来运行,但是A ...

  7. js中以键值对的形式当枚举

    js中以键值对的形式当枚举var Penum= { B: "姓名", C: "所属居委", D: "证件号", E: "性别&qu ...

  8. 【Java面试题】60 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)? 抽象类中是否可以有静态的main方法?

    接口可以继承接口.抽象类可以实现(implements)接口,抽象类可以继承具体类.抽象类中可以有静态的main方法. 问:  抽象类是否可继承实体类 (concrete class) 答: 抽象类是 ...

  9. html文档流和事件流

    文档流: 标准文档流,float position: relative.absolute.fixed可以脱离标准文档流: 回归标准文档流: https://blog.csdn.net/Welkin_q ...

  10. Wex5短信验证

    调了好几天短信验证测试,终于成功,现将全部源代码发给大家,希望对各位有所帮助,少走弯路        Model.prototype.saveUserBtnClick = function(event ...