hdoj 2874 lca裸题

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

题意 n各点 m条变   q个询问 问 i点到j点的最短路径

解析:开始用最短路。。因为询问量大超时了。。然后学了离线lca 。询问的复杂度能到O(1)。真是犀利啊

献上ac代码

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 #include<vector>
  5 using namespace std;
  6 #define Min 10001
  7 #define Max 1000010
  8 
  9 struct st
 10 {
 11     int len;
 12     int x;
 13 }u;
 14 
 15 vector<st> tree[Min],query[Min];
 16 int vis[Min], father[Min], dis[Min], ans[Max];
 17 int n, m, q;
 18 
 19 void Init()
 20 {
 21     int i;
 22     memset(ans,-1,sizeof(ans));
 23     memset(vis,0,sizeof(vis)); 
 24     memset(dis,0,sizeof(dis));
 25     for(i=1;i<=n+1;i++)
 26     {
 27         father[i]=i;
 28         tree[i].clear();
 29         query[i].clear();
 30     }
 31 }
 32 
 33 int find(int x)
 34 {
 35     if(father[x]==x)
 36       return x;
 37      return father[x]=find(father[x]); 
 38 }
 39 
 40 void build_tree(int x,int y,int z)
 41 {
 42     u.x=y,u.len=z;
 43     tree[x].push_back(u);
 44 }
 45 
 46 void add_query(int x,int y,int c)
 47 {
 48     u.len=c,u.x=y;
 49     query[x].push_back(u);
 50     
 51 }
 52 void taijan(int now,int totdis,int root)
 53 {
 54     
 55     int i;
 56     father[now]=now;
 57     dis[now]=totdis;
 58     vis[now]=root;
 59    
 60     for(i=0;i<tree[now].size();i++)
 61     {
 62         
 63        st uu=tree[now][i];
 64         
 65         if(!vis[uu.x])
 66         {
 67             
 68             taijan(uu.x,totdis+uu.len,root);
 69              father[uu.x]=now;
 70           
 71         }          
 72    }
 73     
 74     for(i=0;i<query[now].size();i++)
 75     {
 76          st uu=query[now][i];
 77          if(vis[uu.x])
 78          {
 79                if(vis[uu.x]==root)
 80                {
 81                         
 82                      ans[uu.len]=dis[now]+dis[uu.x]-2*dis[find(uu.x)];
 83                 }
 84           }
 85     }
 86    
 87    
 88 }
 89 
 90 void Pirnt_fun()
 91 {
 92     int i;
 93     for(i=1;i<=q;i++)
 94     {
 95         if(ans[i]==-1)
 96           printf("Not connected\n");
 97         else  
 98           printf("%d\n",ans[i]);
 99     }
100 }
101 
102 int main()
103 {
104 
105     while(scanf("%d %d %d",&n,&m,&q)!=EOF)
106     {
107         Init();
108         int i;
109         for(i=1;i<=m;i++)
110         {
111             int x,y,z;
112             scanf("%d %d %d",&x,&y,&z);
113             build_tree(x,y,z);
114             build_tree(y,x,z);
115         }
116       
117         for(i=1;i<=q;i++)
118         {
119             int start, endl;
120             scanf("%d %d",&start,&endl);
121             add_query(start,endl,i);
122             add_query(endl,start,i);    
123             
124         }
125        for(i=1;i<=n;i++)
126        {
127              if(!vis[i])
128              {
129                  taijan(i,0,i);
130              } 
131           }
132         Pirnt_fun();
133         
134     }
135     return 0;
136 } 

 

 

posted on 2012-10-20 16:06  acmer_acm  阅读(253)  评论(0编辑  收藏  举报