HDU 2874 - Connections between cities(LCA‘离线算法Tarjan)
2015-07-11 09:51
302 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2874
题意:n个点m条边的森林,c个询问,求出两个点的最短路径,若不连接则输出 Not connected。
思路:由于询问c(1~1000000),所以采用LCA的离线算法
由于是森林,则再建立一个点n+1将所以点连接起来,若两个点的最近公共祖先是n+1,则两个点 Not connected。
本题还容易爆内存,要把询问节点的数组设为 short型。
详见http://noalgo.info/476.html
AC.
题意:n个点m条边的森林,c个询问,求出两个点的最短路径,若不连接则输出 Not connected。
思路:由于询问c(1~1000000),所以采用LCA的离线算法
由于是森林,则再建立一个点n+1将所以点连接起来,若两个点的最近公共祖先是n+1,则两个点 Not connected。
本题还容易爆内存,要把询问节点的数组设为 short型。
详见http://noalgo.info/476.html
AC.
#include <iostream> #include <cstdio> #include <cstring> #include <vector> //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int INF = 0x3f3f3f; const int maxn = 10010; const int maxq = 1000010; int far[maxn], rnk[maxn]; int fg(int x) { if(far[x] == x) return x; return far[x] = fg(far[x]); } void unite(int a, int b) { int x = fg(a); int y = fg(b); if(x == y) return; if(rnk[x] <= rnk[y]) far[x] = y, rnk[y] += rnk[x]; else far[y] = x, rnk[x] += rnk[y]; } struct Edge { int to, next, w; }edge[maxn*4]; int head[maxn], tot; void addedge(int u, int v, int w) { edge[tot].to = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++; } short asku[maxq*2], askv[maxq*2]; int askid[maxq*2], asknext[maxq*2], h[maxn]; int tt; void addask(int u, int v, int id) { asku[tt] = u; askv[tt] = v; askid[tt] = id; asknext[tt] = h[u]; h[u] = tt++; } int n, m; int ans[maxq], dis[maxn], anc[maxn]; bool vis[maxn]; void init() { tot = 0; tt = 0; memset(head, -1, sizeof(head)); memset(h, -1, sizeof(h)); memset(vis, 0, sizeof(vis)); memset(dis, 0, sizeof(dis)); memset(anc, 0, sizeof(anc)); memset(ans, 0, sizeof(ans)); for(int i = 0; i <= n+1; ++i) { far[i] = i; rnk[i] = 1; } } void LCA(int u) { anc[u] = u; vis[u] = 1; for(int i = head[u] ; i != -1 ; i = edge[i].next){ int v = edge[i].to; if(!vis[v]){ dis[v] = dis[u] + edge[i].w; LCA(v); unite(u, v); anc[fg(u)] = u; } } for(int i = h[u] ; i != -1 ; i = asknext[i]){ int v = askv[i]; if(vis[v]){ ans[askid[i]] = anc[fg(v)]; } } } int main() { //freopen("in", "r", stdin); int k; while(~scanf("%d %d %d", &n, &m, &k)) { init(); int u, v, w; for(int i = 0; i < m; ++i) { scanf("%d %d %d", &u, &v, &w); addedge(u, v, w); addedge(v, u, w); } for(int i = 0; i < k; ++i) { scanf("%d %d", &u, &v); addask(u, v, i); addask(v, u, i); } for(int i = 1; i <= n; ++i) { if(far[i] == i) { addedge(i, n+1, INF); addedge(n+1, i, INF); } } LCA(n+1); for(int i = 0 ; i < tt; i+=2){ if(ans[askid[i]] != n + 1) printf("%d\n",dis[asku[i]]+dis[askv[i]]-2*dis[ans[askid[i]]]); else printf("Not connected\n"); } } }
相关文章推荐
- HDU 1568
- HDU1290
- HDU1568(Fobonacci公式)
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- HDU 1000
- HDU 1001
- HDU 1622 Trees On The Level
- HDU 1063 Exponentiation
- Hdu5033
- HDU 1166 敌兵布阵
- HDU Rightmost Digit
- hdu 1002
- 贪心 hdu 1003
- hdu 1004