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.有仇恨的骑士不能挨着坐.问有几个骑士不能和任何人形成任何的圆圈. 思路:首先 ...
随机推荐
- gitHub网站上常见英语翻译2
repositories资料库 compilers with rich code analysis APIs.编译器具有丰富的代码分析API. plugins插件 With a variety of ...
- [CTSC2007]数据备份Backup 题解
题意: 一维直线上有n个点,任取2k个互不相同的点组成k条链,求链的最小总长 思路: 1.最优时链不相交,相邻两两相减,将题目转化为:在n-1个数中取互不相邻的k个数使总和最小. 2.贪心取最小的“数 ...
- 显示倒计时,为零时自动点击按钮提交【JavaScript实现】
原文发布时间为:2008-10-17 -- 来源于本人的百度文章 [由搬家工具导入] <html> <head> <title>显示倒计时,完毕提交</tit ...
- jQuery根据属性模糊匹配元素
1.查看带有指定属性的元素: [attribute] 例如: $("div[id]") 2.查看属性值是某个特定值的元素: [attribute=value] 例如: $(&quo ...
- 大话数据结构——KMP算法(还存在问题)
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html /*#include& ...
- Catch The Caw——(广度优先搜索的应用,队列)
抓住那头牛(POJ3278)农夫知道一头牛的位置,想要抓住它.农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000).农夫有 ...
- 从零开始写STL-string类型
class string { public: typedef size_t size_type; typedef char* iterator; typedef char value_type; pr ...
- Beat---hdu2614
http://acm.hdu.edu.cn/showproblem.php?pid=2614 题目大意 题目就不粘了 就是一个简单的深搜 由于我深搜实在是不懂 就在写一个博客记录一下 #in ...
- [Bzoj4260]Codechef REBXOR(trie树)
4260: Codechef REBXOR Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1534 Solved: 669[Submit][Stat ...
- 寒武纪camp Day2
补题进度:8/10 A(计数+BIT) 题意: 给一个长度为n的数组a[],任意选0<=i<=j<n,将a[i]~a[j]从小到大排序,形成新的数组.问有多少个不同的新数组. N,a ...