HDU4612 Warm up —— 边双联通分量 + 重边 + 缩点 + 树上最长路
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4612
Warm up
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 7206 Accepted Submission(s): 1681
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.
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.
1 2
1 3
1 4
2 3
0 0
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 2e5+; struct Edge
{
int to, next;
}edge[MAXN*];
int tot, head[MAXN];
vector<int>g[MAXN]; void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} int index, dfn[MAXN], low[MAXN];
int top, Stack[MAXN], instack[MAXN];
int block, belong[MAXN]; void Tarjan(int u, int pre)
{
dfn[u] = low[u] = ++index;
Stack[top++] = u;
instack[u] = true;
for(int i = head[u]; i!=-; i = edge[i].next)
{
//因为一对点之间可能有多条边,所以不能根据v是否为上一个点来防止边是否被重复访问。而需要根据边的编号
if((i^)==pre) continue;
int v = edge[i].to;
if(!dfn[v])
{
Tarjan(v, i);
low[u] = min(low[u], low[v]);
}
else if(instack[v])
low[u] = min(low[u], dfn[v]);
} if(low[u]==dfn[u])
{
block++;
int v;
do
{
v = Stack[--top];
instack[v] = false;
belong[v] = block;
}while(v!=u);
}
} int diameter, endpoint;
int dfs(int u, int pre, int dep)
{
if(dep>diameter) { endpoint = u; diameter = dep; }
for(int i = ; i<g[u].size(); i++)
if(g[u][i]!=pre)
dfs(g[u][i], u, dep+);
} void init(int n)
{
tot = ;
memset(head, -, sizeof(head)); index = ;
memset(dfn, , sizeof(dfn));
memset(low, , sizeof(low)); top = ;
memset(instack, false, sizeof(instack)); block = ;
for(int i = ; i<=n; i++)
belong[i] = i, g[i].clear();
} int main()
{
int n, m;
while(scanf("%d%d", &n, &m) && (n||m) )
{
init(n);
for(int i = ; i<=m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
} Tarjan(, -);
for(int u = ; u<=n; u++)
for(int i = head[u]; i!=-; i = edge[i].next)
{
int v = edge[i].to;
if(belong[u]!=belong[v])
g[belong[u]].push_back(belong[v]);
} endpoint = , diameter = ;
dfs(, -, );
dfs(endpoint, -, );
printf("%d\n", block--diameter);
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 2e18;
const int MAXN = 2e5+; struct Edge
{
int from, to, next;
}edge[MAXN*];
int tot, head[MAXN]; void addedge(int u, int v)
{
edge[tot].from = u;
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} int index, dfn[MAXN], low[MAXN];
int top, Stack[MAXN], instack[MAXN];
int block, belong[MAXN]; void Tarjan(int u, int pre)
{
dfn[u] = low[u] = ++index;
Stack[top++] = u;
instack[u] = true;
for(int i = head[u]; i!=-; i = edge[i].next)
{
//因为一对点之间可能有多条边,所以不能根据v是否为上一个点来防止边是否被重复访问。而需要根据边的编号
if((i^)==pre) continue;
int v = edge[i].to;
if(!dfn[v])
{
Tarjan(v, i);
low[u] = min(low[u], low[v]);
}
else if(instack[v])
low[u] = min(low[u], dfn[v]);
} if(low[u]==dfn[u])
{
block++;
int v;
do
{
v = Stack[--top];
instack[v] = false;
belong[v] = block;
}while(v!=u);
}
} int diameter, endpoint;
int dfs(int u, int pre, int dep)
{
if(dep>diameter) { endpoint = u; diameter = dep; }
for(int i = head[u]; i!=-; i = edge[i].next)
if(edge[i].to!=pre)
dfs(edge[i].to, u, dep+);
} void init(int n)
{
tot = ;
memset(head, -, sizeof(head)); index = ;
memset(dfn, , sizeof(dfn));
memset(low, , sizeof(low)); top = ;
memset(instack, false, sizeof(instack)); block = ;
for(int i = ; i<=n; i++)
belong[i] = i;
} int main()
{
int n, m;
while(scanf("%d%d", &n, &m) && (n||m) )
{
init(n);
for(int i = ; i<=m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
} Tarjan(, -);
tot = ;
memset(head, -, sizeof(head));
for(int i = ; i<*m; i++)
{
int u = edge[i].from, v = edge[i].to;
if(belong[u]!=belong[v])
addedge(belong[u], belong[v]);
} endpoint = , diameter = ;
dfs(, -, );
dfs(endpoint, -, );
printf("%d\n", block--diameter);
}
}
HDU4612 Warm up —— 边双联通分量 + 重边 + 缩点 + 树上最长路的更多相关文章
- POJ-3352-RoadConstruction(边双联通分量,缩点)
链接:https://vjudge.net/problem/POJ-3352#author=0 题意: 给一个无向连通图,至少添加几条边使得去掉图中任意一条边不改变图的连通性(即使得它变为边双连通图) ...
- HDU4738 Caocao's Bridges —— 边双联通分量 + 重边
题目链接:https://vjudge.net/problem/HDU-4738 A network administrator manages a large network. The networ ...
- [J]computer network tarjan边双联通分量+树的直径
https://odzkskevi.qnssl.com/b660f16d70db1969261cd8b11235ec99?v=1537580031 [2012-2013 ACM Central Reg ...
- 【UVA10972】RevolC FaeLoN (求边双联通分量)
题意: 给你一个无向图,要求把所有无向边改成有向边,并且添加最少的有向边,使得新的有向图强联通. 分析: 这题的解法还是很好想的.先用边双联通分量缩点,然后找新图中入度为0和为1的点,入度为0则ans ...
- ARC062 - F. Painting Graphs with AtCoDeer (Polya+点双联通分量)
似乎好久都没写博客了....赶快来补一篇 题意 给你一个 \(n\) 个点 , 没有重边和自环的图 . 有 \(m\) 条边 , 每条边可以染 \(1 \to k\) 中的一种颜色 . 对于任意一个简 ...
- POJ2942 Knights of the Round Table【Tarjan点双联通分量】【二分图染色】【补图】
LINK 题目大意 有一群人,其中有一些人之间有矛盾,现在要求选出一些人形成一个环,这个环要满足如下条件: 1.人数大于1 2.总人数是奇数 3.有矛盾的人不能相邻 问有多少人不能和任何人形成任何的环 ...
- lightoj 1300 边双联通分量+交叉染色求奇圈
题目链接:http://lightoj.com/volume_showproblem.php?problem=1300 边双连通分量首先dfs找出桥并标记,然后dfs交叉着色找奇圈上的点.这题只要求在 ...
- HDU5409---CRB and Graph 2015多校 双联通分量缩点
题意:一个联通的无向图, 对于每一条边, 若删除该边后存在两点不可达,则输出这两个点, 如果存在多个则输出第一个点尽可能大,第二个点尽可能小的. 不存在输出0 0 首先 若删除某一条边后存在多个联通分 ...
- poj2942(双联通分量,交叉染色判二分图)
题意:一些骑士,他们有些人之间有矛盾,现在要求选出一些骑士围成一圈,圈要满足如下条件:1.人数大于1.2.总人数为奇数.3.有仇恨的骑士不能挨着坐.问有几个骑士不能和任何人形成任何的圆圈. 思路:首先 ...
随机推荐
- [Android]使用button切换TextView可见和不可见
<Button android:id="@+id/btnTest" android:layout_width="match_parent" android ...
- 【转】C# windows服务的创建与调试
Windows Service这一块并不复杂,但是注意事项太多了,网上资料也很凌乱,偶尔自己写也会丢三落四的.所以本文也就产生了,本文不会写复杂的东西,完全以基础应用的需求来写,所以不会对Window ...
- Python2和Python3共存安装robotframework
1.下载Python2.Python3安装包 https://www.python.org/ 2.下载pip.tar.gz https://pypi.python.org/pypi/pip#downl ...
- 病毒的侵扰和再侵扰两道AC自动机的应用
HDU2896 病毒的侵扰 http://vjudge.net/problem/viewProblem.action?id=16404 题目大意: 记录每个病毒的编号,并给出一些网站的源码,分别输出网 ...
- middle(bzoj 2653)
Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序列s. 回答Q个这样的询问:s的左端点在[a,b ...
- SQL SERVER 2012 第三章 使用INSERT语句添加数据
INSERT [TOP (<expression>) [PERCENT] [INTO] <tabular object>[(column list)][OUTPUT <o ...
- python学习之-- assert断言
assert 断言作用:断言是声明其布尔值必须为真的判定,如果发生异常就说明表达示为假.可以理解assert断言语句为raise-if-not,用来测试表示式,其返回值为假,就会触发异常.举例如下:a ...
- THUPC2018看题总结
THUPC2018看题总结 #6387. 「THUPC2018」绿绿与串串 / String 据说是签到题啊. 首先根据题目的意思,我们发现如果能找到那个最后一次选择的对称轴岂不是美滋滋. 自然地,我 ...
- 洛谷——P2820 局域网
P2820 局域网 题目背景 某个局域网内有n(n<=100)台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成 ...
- spring mvc get请求也可以接受DTO对象
spring mvc get请求也可以接受DTO对象,比如:url上面你还是将参数&符号连接起来,并自动封装进一个DTO对象里. 只有@RequestBody注解spring mvc才会从ht ...