CodeForces 160D Edges in MST (tarjan)
来源:互联网 发布:炉石淘宝买友谊赛值吗 编辑:程序博客网 时间:2024/05/17 07:57
题目链接:http://codeforces.com/problemset/problem/160/D
题意:给出一个n个点m条边(无自环无重边)的无向图,求问它的所有最小生成树中:哪些边在所有最小生成树中都出现、那些可能出现、那些都不出现。
思路:首先有一个结论:把一个连通无向图的生成树的边按权值递增排序,称排好序的边权列表为有序边权列表,则任意两棵最小生成树的有序边权列表是相同的。因此,借助Kruskal算法思想,先把所有边按权值按从小到大排序,然后每次对权值相同的边一起处理,如果某条边的两个顶点属于同一集合,则该边一定不存在于任何最小生成树(因为会形成环,而环中的其他边是上一次处理权值更小的边时加进去的)。若不在同一集合中,则在这两个集合间添加一条无向边,那么这些边有可能出现在该图的最小生成树中;再进一步,这些边所形成的的所有连通块中,如果存在桥,那么这条边即是在所有最小生成树都存在的边。桥的寻找可以借助tarjan算法(注意dfs时的fa应该是边的标号而不是点的标号,因为上述连边过程中可能存在并查集的两个集合间连多条边,即两点间有多条边)。
#include<cstdio>#include<cstring>#include<string>#include<cctype>#include<iostream>#include<set>#include<map>#include<vector>#include<stack>#include<queue>#include<algorithm>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef long long LL;using namespace std;typedef pair<int, int> P;const int maxn = 1e5 + 10;const int INF = 1e9 + 10;struct Edge { int from, to, cost, id, st; Edge() {} Edge(int u, int v, int c, int id, int st) : from(u), to(v), cost(c), id(id), st(st) {} bool operator < (const Edge &rhs) const { return cost < rhs.cost; }}edge[maxn];vector<P> G[maxn];int pre[maxn], dfs_clock;int dfs(int u, int fa_id) { int lowu = pre[u] = ++dfs_clock; for(int i = 0; i < G[u].size(); i++) { int v = G[u][i].first, id = G[u][i].second; if(fa_id == id) continue; if(!pre[v]) { int lowv = dfs(v, id); lowu = min(lowu, lowv); if(lowv > pre[u]) edge[id].st = 2; } else lowu = min(lowu, pre[v]); } return lowu;}int fa[maxn], ans;int find(int x) { return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);}bool cmp(const Edge& A, const Edge &B) { return A.id < B.id;}int main() { int n, m; scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) fa[i] = i; for(int i = 0; i < m; i++) { int u, v, c; scanf("%d%d%d", &u, &v, &c); edge[i] = Edge(u, v, c, i+1, 0); } sort(edge, edge+m); for(int i = 0; i < m; i++) { int s = i, e = i; //处理权值相同的边 while(e+1 < m && edge[e+1].cost == edge[s].cost) e++; for(int j = s; j <= e; j++) { int x = find(edge[j].from), y = find(edge[j].to); if(x == y) continue; G[x].push_back(P(y, j)); G[y].push_back(P(x, j)); edge[j].st = 1; } for(int j = s; j <= e; j++) { int x = find(edge[j].from), y = find(edge[j].to); if(x == y || pre[x]) continue; dfs(x, -1); } for(int j = s; j <= e; j++) { int x = find(edge[j].from), y = find(edge[j].to); if(x == y) continue; G[x].clear(); G[y].clear(); pre[x] = pre[y] = 0; fa[x] = y; } i = e; } sort(edge, edge+m, cmp); for(int i = 0; i < m; i++) { if(edge[i].st == 0) printf("none\n"); else if(edge[i].st == 1) printf("at least one\n"); else printf("any\n"); } return 0;}
0 0
- CodeForces 160D Edges in MST (tarjan)
- Codeforces 160D Edges in MST
- [Codeforces]160D - Edges in MST
- codeforces 160D Edges in MST
- codeforces 160D - Edges in MST
- CodeForces 160D Edges in MST 题解
- CodeForces 160D - Edges in MST kruskal+tarjan求无向图的桥
- CF 160D Edges in MST
- Codeforces 160D Edges in MST【思维+并查集+求桥(有重边)】
- Codeforces160D Edges in MST
- Orientation of Edges CodeForces
- UVA 11747 - Heavy Cycle Edges(MST)
- UVA 11747 Heavy Cycle Edges(MST)
- CodeForces 131D Subway [tarjan+最短路]
- Operations on edges in polyhedron
- codeforces D. Distance in Tree
- 【codeforces】494D. Birthday 【树型DP+离线tarjan求LCA】
- Codeforces Problem 711D Directed Roads(Tarjan判环)
- javaScript高级程序设计学习笔记(2)
- ssm中遇到的报错
- document.layers document.all
- ---php---小程序《》
- Bootstrap学习笔记(一)
- CodeForces 160D Edges in MST (tarjan)
- 源代码品牌升级为源码时代
- $.ajax( )、$.getJson( )及JSON格式转换
- MyBatis--动态SQL---where标签
- Delaunay三角剖分算法
- [HDU 2841]Visible Trees:容斥原理
- LeetCode 118. Pascal's Triangle
- 在Idea中连接数据库并生成实体类 -- hibernate
- HDU2196树形dp