zoukankan      html  css  js  c++  java
  • How far away ?

    hdu2586:http://acm.hdu.edu.cn/showproblem.php?pid=2586

    题意:给你一棵树,然后询问任意两点之间的距离。

    题解1:直接用spfa,求最短路,因为只有40000-1条边,200个查询,所以应该可以过。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #define inf 2000000000
     7 using namespace std;
     8 const int N=1e4*4+5;
     9 long long dist[N],n,m;
    10 bool vis[N];
    11 struct Node{
    12   int v;
    13   int next;
    14   int w;
    15 }edge[N*4];
    16 int head[N],cnt;
    17 void init(){
    18   memset(head,-1,sizeof(head));
    19   cnt=0;
    20 }
    21 void add(int u,int v,int w){
    22      edge[cnt].v=v;
    23      edge[cnt].next=head[u];
    24      edge[cnt].w=w;
    25      head[u]=cnt++;
    26      edge[cnt].v=u;
    27      edge[cnt].next=head[v];
    28      edge[cnt].w=w;
    29      head[v]=cnt++;
    30 }
    31 
    32 long long spfa(int u,int ed){
    33   for(int i=1;i<=n;i++){
    34     dist[i]=inf;
    35     vis[i]=0;
    36   }
    37   queue<int>Q;
    38   dist[u]=0;
    39   vis[u]=1;
    40   Q.push(u);
    41   while(!Q.empty()){
    42       int d=Q.front();
    43       Q.pop();
    44       vis[d]=0;
    45       for(int i=head[d];i!=-1;i=edge[i].next){
    46          int v=edge[i].v;
    47          if(dist[v]>dist[d]+edge[i].w){
    48             dist[v]=dist[d]+edge[i].w;
    49             if(!vis[v]){
    50                 Q.push(v);
    51                 vis[v]=1;
    52             }
    53          }
    54       }
    55   }
    56   return dist[ed];
    57 }
    58 int cas,t1,t2,t3;
    59 int main(){
    60     scanf("%d",&cas);
    61     while(cas--){
    62         scanf("%d%d",&n,&m);
    63         init();
    64         for(int i=1;i<n;i++){
    65             scanf("%d%d%d",&t1,&t2,&t3);
    66             add(t1,t2,t3);
    67         }
    68         for(int i=1;i<=m;i++){
    69             scanf("%d%d",&t1,&t2);
    70             printf("%I64d
    ",spfa(t1,t2));
    71         }
    72     }
    73 }
    View Code

    题解2:LCA来搞,记录每个点到根节点的距离,然后找到最近公共祖先,最后的结果就是dist[u]+dist[v]-2*dist[LCA(u,v)];其中还有很多问题要考虑,细节问题,

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 using namespace std;
      6 #define N 40001
      7 int n,m;
      8 int fa[N],indegree[N];//并查集和统计度数
      9 
     10 int vis[N],ances[N];//DFS过程中标记是否访问以及记录祖先
     11 
     12 int head[N],cnt,sum[N];;//记录查询的变量,sum[i],表示第3个点查询的次数,可以解决重复查询同一个值
     13 
     14 int ans[N];//记录最终查询结果
     15 int head2[N],cnt2;//记录原来树的变量
     16 int dist[N];//记录到根节点的距离
     17 struct Node{
     18    int v;
     19    int next;
     20    int id;
     21 }edge[N*4],hash[N*4];//分贝存查询和原树
     22 
     23 void init1(){
     24   memset(head,-1,sizeof(head));
     25   memset(ans,-1,sizeof(ans));
     26   memset(head2,-1,sizeof(head2));
     27   memset(sum,0,sizeof(sum));
     28   cnt=cnt2=0;
     29 }
     30 void add(int u,int v,int w){
     31     edge[cnt].v=v;
     32     edge[cnt].id=w;
     33     edge[cnt].next=head[u];
     34     head[u]=cnt++;
     35     edge[cnt].v=u;
     36     edge[cnt].id=w;
     37     edge[cnt].next=head[v];
     38     head[v]=cnt++;
     39 }
     40 void add1(int u,int v,int w){
     41     hash[cnt2].v=v;
     42     hash[cnt2].id=w;
     43     hash[cnt2].next=head2[u];
     44     head2[u]=cnt2++;
     45 }
     46 void init2(){
     47     for(int i=0;i<=n;i++){
     48         fa[i]=i;
     49         indegree[i]=0;
     50         vis[i]=0;
     51         ances[i]=0;
     52     }
     53 }
     54 int find(int x){
     55    int s;
     56    for(s=x;s!=fa[s];s=fa[s]);
     57    while(s!=x){
     58      int temp=fa[x];
     59      fa[x]=s;
     60      x=temp;
     61    }
     62    return s;
     63 }
     64 void unio(int x,int y){
     65     int fx=find(x),fy=find(y);
     66     if(fx==fy) return ;
     67      fa[fy]=fx;
     68 }
     69 void Tarjan(int u,int len){
     70     ances[u]=u;
     71     dist[u]=len;
     72     for(int i=head2[u];i!=-1;i=hash[i].next){
     73         int v=hash[i].v;
     74         int w=hash[i].id;
     75         Tarjan(v,len+w);
     76         unio(u,v);
     77         ances[find(u)]=u;
     78     }
     79     vis[u]=1;
     80     for(int i=head[u];i!=-1;i=edge[i].next){
     81         int v=edge[i].v;
     82         if(vis[v]==1&&sum[v]>0){
     83             ans[edge[i].id]=dist[u]+dist[v]-2*dist[ances[find(v)]];
     84             sum[v]--;
     85         }
     86     }
     87 }
     88 int main(){
     89     int t;
     90     int i,j;
     91     scanf("%d",&t);
     92     while(t--){
     93         scanf("%d",&n);
     94         scanf("%d",&m);//询问的次数
     95         init1();init2();
     96         int s,d,l;
     97         for(i=1;i<=n-1;i++){
     98             scanf("%d%d%d",&s,&d,&l);
     99             if(s>d)swap(s,d);//保证是建立是一棵树
    100             add1(s,d,l);
    101             indegree[d]++;
    102         }
    103           for(int i=1;i<=m;i++){
    104                 scanf("%d%d",&s,&d);
    105                  sum[d]++;
    106                  sum[s]++;
    107                  add(s,d,i);
    108              }
    109         for(j=1;j<=n;j++){
    110             if(indegree[j]==0){
    111                 Tarjan(j,0);
    112                 break;
    113             }
    114         }
    115        for(int i=1;i<=m;i++){
    116         printf("%d
    ",ans[i]);
    117       }
    118     }
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    服务器监控
    hadoop
    tomcat7 配置
    tomcat
    列表加载
    自适应网页设计(Responsive Web Design)
    Android Native 代码NDK开发学习笔记
    NDK开发历程(一):android native code的调试方法
    Android原生(Native)C开发之一:环境搭建篇
    ajaxfileupload 传参数
  • 原文地址:https://www.cnblogs.com/chujian123/p/3871430.html
Copyright © 2011-2022 走看看