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. Jquery仿IGoogle实现可拖动窗口(源码)

    google可谓是ajax的特效用的淋漓尽致,google suggest, google map,igoogle 可拖动窗口等等...今天仿照iGoogle做了一个简单的小demo. 这个的demo ...

  2. 关于Cocos Creator用js脚本代码播放骨骼动画的步骤和注意事项

    步骤: 1.用cc.find()方法找到相应的骨骼动画节点,并把这个对象赋值给一个var出来的新对象. 具体代码:var spineboy_anim = cc.find("UI_Root/a ...

  3. 将android程序中的数据库导出到SD卡

    private void copyDBToSDcrad() { String DATABASE_NAME = "数据库文件名"; String oldPath = "da ...

  4. sourcetree管理git

    下载地址: https://www.sourcetreeapp.com/ 跳过注册: 到注册登录页面打开文件目录%LocalAppData%\Atlassian\SourceTree\ 会发现有个文件 ...

  5. 工厂模式(factory pattern) ------创造型模式

    创建型模式 简单工厂模式的缺点是: 当我们引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,需要修改工厂类的方法,违反了“开闭原则”. 工厂模式提供了一个抽象工厂接口来声明抽象工厂方 ...

  6. WPF 在事件中绑定命令

    导航:MVVMLight系列文章目录:<关于 MVVMLight 设计模式系列> 其实这也不属于MVVMLight系列中的东东了,没兴趣的朋友可以跳过这篇文章,本文主要介绍如何在WPF中实 ...

  7. ios 生成一个动态的随机的头像/随机数的操作

    在写项目的时候,可能会遇到这种情况,用到集中随机的颜色,或者头像等, 首先:把所需要的图片放进一个数组当中 imgsAry = @[@"t1.png",@"t2.png& ...

  8. 批处理bat文件dos命令复制文件

    ::将“C:\Users\ZZ\Desktop\快捷处理\我我我哦我”路径下的文件复制到“C:\Temp\我我我哦我”路径下::/S表示“复制目录和子目录,除了空的.”::/E表示“复制目录和子目录, ...

  9. mybatis 返回值类型是Map

    <select id="selectByMemberKey" resultType="java.util.HashMap"> SELECT memb ...

  10. APP的缓存文件放在哪里?

    只要是需要进行联网获取数据的APP,都会在本地产生缓存文件.那么,这些缓存文件到底放在什地方合适呢?系统有没有给我们提供建议的缓存位置呢?不同的缓存位置有什么不同呢? 考虑到卸载APP必须删除缓存 在 ...