HDU 3072 Intelligence System (tarjan-scc缩点 + 最小树形图)
2015-11-04 00:26
477 查看
题意:
给了一个含有N<=50000个节点的有向图,图中的两点间通信付出代为经过的边权之和,但是如果这两个点之间相互可达,代价为0
问从给定的节点向其他所有的点通信,所花费的最小代价是多少?
分析:
相互可达的就是一个强联通分量,先缩点成为DAG,最小代价就是最小树形图,因为scc内部都是0,DAG无圈根据最小树形图算法思想,直接把新图最小入边权全部加起来就是ans了
代码:
给了一个含有N<=50000个节点的有向图,图中的两点间通信付出代为经过的边权之和,但是如果这两个点之间相互可达,代价为0
问从给定的节点向其他所有的点通信,所花费的最小代价是多少?
分析:
相互可达的就是一个强联通分量,先缩点成为DAG,最小代价就是最小树形图,因为scc内部都是0,DAG无圈根据最小树形图算法思想,直接把新图最小入边权全部加起来就是ans了
代码:
// // Created by TaoSama on 2015-11-03 // Copyright (c) 2015 TaoSama. All rights reserved. // //#pragma comment(linker, "/STACK:1024000000,1024000000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <set> #include <vector> using namespace std; #define pr(x) cout << #x << " = " << x << " " #define prln(x) cout << #x << " = " << x << endl const int N = 5e4 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7; const int M = 1e5 + 10; int n, m; struct Edge { int v, nxt, c; } edges[M]; int head , cnt; void add_edge(int u, int v, int c) { edges[cnt] = (Edge) {v, head[u], c}; head[u] = cnt++; } int in , id , dfn , low , stk , dfsNum, top, scc; void tarjan(int u) { dfn[u] = low[u] = ++dfsNum; in[u] = true; stk[++top] = u; for(int i = head[u]; ~i; i = edges[i].nxt) { int v = edges[i].v; if(!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if(in[v]) low[u] = min(low[u], dfn[v]); } if(low[u] == dfn[u]) { ++scc; while(true) { int v = stk[top--]; id[v] = scc; in[v] = false; if(v == u) break; } } } void init() { scc = cnt = top = dfsNum = 0; memset(head, -1, sizeof head); memset(dfn, 0, sizeof dfn); memset(low, 0, sizeof low); memset(in, 0, sizeof in); } int main() { #ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin); // freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout); #endif ios_base::sync_with_stdio(0); while(scanf("%d%d", &n, &m) == 2) { init(); for(int i = 1; i <= m; ++i) { int u, v, c; scanf("%d%d%d", &u, &v, &c); add_edge(u, v, c); } for(int i = 0; i < n; ++i) if(!dfn[i]) tarjan(i); memset(in, 0x3f, sizeof in); for(int i = 0; i < n; ++i) { int u = id[i]; for(int j = head[i]; ~j; j = edges[j].nxt) { int v = id[edges[j].v]; if(u != v) in[v] = min(in[v], edges[j].c); } } int ans = 0; //no "in" edge of root, in[root] = INF; for(int i = 1; i <= scc; ++i) if(in[i] != INF) ans += in[i]; printf("%d\n", ans); } return 0; }
相关文章推荐
- 最小树形图模板朱刘算法分享
- HDU1289 Tarjan-模板题
- UVA 11770 Lighting Away
- POJ2553 The Bottom of a Graph Tarjan 矩阵 pascal 解题报告
- POJ3180 The Cow Prom Tarjan 链接表 pascal 解题报告
- POJ1986 Distance Queries LCA pascal 解题报告
- tarjan
- [BZOJ1179][APIO2009][Tarjan][拓扑排序][递推]Atm
- [BZOJ2330][SCOI2011][拓扑排序][强连通分量][Tarjan]Candy
- [BZOJ1093][ZJOI2007][Tarjan][DP]最大半联通子图
- MZ Training 2014 #4 C题
- 图论算法(6) --- Tarjan算法求强连通分量
- 图论算法(6)(更新版) --- Tarjan算法求强连通分量
- [BZOJ1051/POJ2186]Popular Cows
- POJ3114 Country in Wars Tarjan+Dij
- poj 3352 双连通分量
- hdu 4738 边双连通&桥,有重边情况
- poj 1236 强连通分量+缩点
- POJ 3177 / POJ 3352 : Redundant Paths / Road Construction - 边双连通分量,缩点
- 【Lightoj 1251 Forming the Council】& Tarjan & 2 - SAT