HDU2874 Connections between cities LCA+并查集

      给出一个森林,问u到v的最短距离

    可以先对整个图做一次并查集求出个联通分块

    对于每一个联通块进行一次Tarjan,不在一个块里面的,ans = -1;

    这样写就是复杂度还高一点。。

 

     

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 using namespace std;
  5 const int maxn = 20005;
  6 struct edge
  7 {
  8     int v,w,next;
  9 }e[maxn];
 10 struct node
 11 {
 12     int v,ans,next;
 13 }q[maxn*100];
 14 int cnt,cnt_a,h1[maxn],h2[maxn],d[maxn];
 15 int fa[maxn],fat[maxn],vis[maxn],vis1[maxn];
 16 void init(int n)
 17 {
 18     memset(h1,-1,sizeof(h1));
 19     memset(h2,-1,sizeof(h2));
 20     memset(vis,0,sizeof(vis));
 21     memset(vis1,0,sizeof(vis1));
 22     cnt = 0;cnt_a = 0;
 23     for(int i = 1;i<=n;++i)fa[i] = i,fat[i] = i;
 24 }
 25 int findd(int x)
 26 {
 27     int ret = x;
 28     while(ret!=fa[ret])ret = fa[ret];
 29     while(x!=ret)
 30     {
 31         int t = fa[x];
 32         fa[x] =  ret;
 33         x = t;
 34     }
 35     return ret;
 36 }
 37 int finddd(int x)
 38 {
 39     int ret = x;
 40     while(ret!=fat[ret])ret=fat[ret];
 41     while(x!=ret)
 42     {
 43         int t = fat[x];
 44         fat[x] = ret;
 45         x = t;
 46     }
 47     return ret;
 48 }
 49 void add(int u,int v,int w)
 50 {
 51     e[cnt].v = v;e[cnt].w = w;
 52     e[cnt].next = h1[u];
 53     h1[u] = cnt++;
 54 }
 55 void add_a(int u,int v)
 56 {
 57     q[cnt_a].v = v;
 58     q[cnt_a].next = h2[u];
 59     h2[u] = cnt_a++;
 60 }
 61 void lca(int rt)
 62 {
 63     vis[rt] = 1;
 64     for(int i = h1[rt];i!=-1;i=e[i].next)if(!vis[e[i].v])
 65     {
 66         d[e[i].v] = d[rt]+e[i].w;
 67         lca(e[i].v);
 68         fat[e[i].v] = rt;
 69     }
 70     vis1[rt] = 1;
 71     for(int i = h2[rt];i!=-1;i=q[i].next)
 72         if(findd(q[i].v)!=findd(rt))q[i].ans = -1;
 73         else
 74         {
 75             if(vis1[q[i].v])
 76                 q[i].ans = q[i^1].ans = d[rt]+d[q[i].v]-2*d[finddd(q[i].v)];
 77         }
 78 }
 79 int main()
 80 {
 81 //    freopen("in.txt","r",stdin);
 82     int n,m,k;
 83     while(~scanf("%d%d%d",&n,&m,&k))
 84     {
 85         init(n);
 86         for(int i = 1;i<=m;++i)
 87         {
 88             int x,y,z;scanf("%d%d%d",&x,&y,&z);
 89             add(x,y,z);
 90             add(y,x,z);
 91             fa[findd(x)] = findd(y);
 92         }
 93 
 94         for(int i = 1;i<=k;++i)
 95         {
 96             int u,v;scanf("%d%d",&u,&v);
 97             add_a(u,v);
 98             add_a(v,u);
 99         }
100         for(int i = 1;i<=n;++i)if(fa[i]==i)
101             lca(i);
102         for(int i = 0;i<cnt_a;i+=2)//printf("i=%d  %d\n",i,q[i].ans);
103             if(q[i].ans==-1)printf("Not connected\n");
104             else printf("%d\n",q[i].ans);
105     }
106     return 0;
107 }

 

posted on 2015-05-07 16:30  round_0  阅读(138)  评论(0编辑  收藏  举报

导航