HDU 2874Connections between cities LCA

来源:互联网 发布:懒人听书 源码 编辑:程序博客网 时间:2024/05/16 15:22

题目:http://acm.hdu.edu.cn/showproblem.php?pid=2874


题意:给定一个图,不一定连通,求任意两点间的最短距离,不能相互到达就输出Not connected


思路:tarjan求LCA,然后dist[v,u] = dist[v] + dist[u] - 2 * dist[LCA(v, u)]


总结:题目不难,但是对内存限制好严格!之前我用两个数组储存查询用来判断是否连通,直接MLE了,改用了其他判断连通的方式

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;typedef long long ll;const int N = 10001;struct edge1{    int to, cost, next;}G1[N*2];struct edge2{    int to, ind, next;}G2[N*200];int head1[N], head2[N], par[N];int dist[N], res[N*100];int cnt1, cnt2;bool vis[N];int n, m, k;void init(){    for(int i = 1; i <= n; i++)        par[i] = i;    memset(head1, -1, sizeof head1);    memset(head2, -1, sizeof head2);    memset(vis,0, sizeof vis);    cnt1 = cnt2 = 0;}void add_edge1(int v, int u, int cost){    G1[cnt1].to = u;    G1[cnt1].cost = cost;    G1[cnt1].next = head1[v];    head1[v] = cnt1++;}void add_edge2(int v, int u, int ind){    G2[cnt2].to = u;    G2[cnt2].ind = ind;    G2[cnt2].next = head2[v];    head2[v] = cnt2++;}int ser(int v){    int r = v, i = v, j;    while(r != par[r]) r = par[r];    while(i != r) j = par[i], par[i] = r, i = j;    return r;}void tarjan_lca(int v){    vis[v] = true;    int u;    for(int i = head1[v]; i != -1; i = G1[i].next)        if(!vis[u=G1[i].to])        {            dist[u] = dist[v] + G1[i].cost;            tarjan_lca(u);            par[u] = v;        }    for(int i = head2[v]; i != -1; i = G2[i].next)        if(vis[u=G2[i].to] && dist[u] != -1) /*不满足条件则查询的两点不连通*/            res[G2[i].ind] = dist[v] + dist[u] - 2 * dist[ser(u)];        else res[G2[i].ind] = -1;}int main(){    int a, b, c;    while(~ scanf("%d%d%d", &n, &m, &k))    {        init();        for(int i = 0; i < m; i++)        {            scanf("%d%d%d", &a, &b, &c);            add_edge1(a, b, c);            add_edge1(b, a, c);        }        for(int i = 0; i < k; i++)        {            scanf("%d%d", &a, &b);            add_edge2(a, b, i);            add_edge2(b, a, i);        }        for(int i = 1; i <= n; i++)            if(!vis[i])            {                memset(dist, -1, sizeof dist); /*每次置为-1,用来判断是否连通*/                dist[i] = 0;                tarjan_lca(i);            }        for(int i = 0; i < k; i++)            if(res[i] == -1) printf("Not connected\n");            else printf("%d\n", res[i]);    }    return 0;}


0 0
原创粉丝点击