HDU - 3394 Railway(连通分量+环)
来源:互联网 发布:mysql和oracle的关系 编辑:程序博客网 时间:2024/05/21 09:41
题目大意:有一个人奇怪的人想要铺路,这个人想把每个环都铺上石头,但是铺石头时不能重复铺,如果重复铺的话,这条边就算损坏
问这个人要损坏多少条边,有多少条边可以不用铺石头
解题思路:不用铺石头的边肯定是桥,因为桥不属于任意一个环
接着判断一下有多少条边会冲突,首先,一个环的话肯定是点-双连通,但点-双连通不一定是个环,所以这个要判断一下。
一个正常的环是要满足 边数=点数 的,如果边数比点数多了,证明这个环被分割成至少三个环了(一个最外围的环,两个被分的小环),可以看出,这三个环每条边都冲突
所以只要满足边数>点数的,都可以证明这个环的所有边冲突
#include <cstdio>#include <cstring>#include <vector>using namespace std;#define N 10010#define M 200010#define min(a,b) ((a) < (b) ? (a): (b))struct Edge{ int from, to, next, id; Edge() {} Edge(int from, int to) :from(from), to(to){}}E[M];int n, m, tot, dfs_clock, bnum, bcc_cnt, top;int head[N], pre[N], stack[M], low[N], num[N];vector<int> edge[N];bool vis[N];void AddEdge(int u, int v) { E[tot].from = u; E[tot].to = v; E[tot].next = head[u]; E[tot].id = tot; head[u] = tot++; u = u ^ v; v = u ^ v; u = v ^ u; E[tot].from = u; E[tot].to = v; E[tot].next = head[u]; E[tot].id = tot; head[u] = tot++;}void init() { memset(head, -1, sizeof(head)); tot = 0; int u, v; for (int i = 0; i < m; i++) { scanf("%d%d", &u, &v); AddEdge(u, v); }}void dfs(int u, int fa) { pre[u] = low[u] = ++dfs_clock; for (int i = head[u]; i != -1; i = E[i].next) { int v = E[i].to; if (!pre[v]) { stack[++top] = E[i].id; dfs(v, u); low[u] = min(low[u], low[v]); if (low[v] >= pre[u]) { bcc_cnt++; edge[bcc_cnt].clear(); int x, id; while (1) { id = stack[top--]; edge[bcc_cnt].push_back(id); x = E[id].from; if (x == u) break; } if (low[v] > pre[u]) bnum++; } } else if(pre[v] < pre[u] && v != fa) { low[u] = min(low[u], pre[v]); stack[++top] = E[i].id; } }}void solve() { memset(pre, 0, sizeof(pre)); dfs_clock = bcc_cnt = bnum = top = 0; for (int i = 0; i < n; i++) if (!pre[i]) dfs(i, -1); int ans = 0; for (int i = 1; i <= bcc_cnt; i++) { for (int j = 0; j < n; j++) vis[j] = false; int size = edge[i].size(), cnt = 0; for (int j = 0; j < size; j++) { if (!vis[E[edge[i][j]].from]) { vis[E[edge[i][j]].from] = true; cnt++; } if (!vis[E[edge[i][j]].to]) { vis[E[edge[i][j]].to] = true; cnt++; } } if (size > cnt) ans += size; } printf("%d %d\n", bnum, ans);}int main() { while (scanf("%d%d", &n, &m) != EOF && n + m) { init(); solve(); } return 0;}
0 0
- HDU - 3394 Railway(连通分量+环)
- hdu 3394 railway 点连通分量判环
- HDU 3394 Railway (点双联通分量+桥)
- hdu 3594 强连通分量加环
- HDU 3394Railway
- HDU-3394 Railway
- HDU 3394Railway( tarjan)
- hdu 3072(强连通分量)
- hdu 2767(强连通分量)
- hdu 1269 强连通分量
- HDU 1827 强连通分量
- HDU 1269 强连通分量
- hdu-4612-强连通分量
- HDU 2767 强连通分量
- hdu 2767强连通分量
- HDU 1236 强连通分量
- hdu 1827强连通分量
- HDU 5934 强连通分量
- HDU - 2460 Network(桥+LCA)
- [080816]ルーデシア~Spidering with Scraping~【日文硬盘版】(带日本语启动补丁)
- 阿里巴巴面试专场
- 数论小知识更新ING
- asp.net代码中尖括号和百分号的用法
- HDU - 3394 Railway(连通分量+环)
- hdu 2665 划分树
- Cocos2d-x 2.0 TestCpp框架源码分析
- Java——网络编程
- HDU - 2586 How far away ?(LCA)
- ASP.NET之GridView常用方法总结
- Induction to Hadoop
- HDU - 2874 Connections between cities(LCA)
- MSP430应用技巧1:COFF ABI与EABI