zoukankan      html  css  js  c++  java
  • hdu 2586【lca的tarjan算法】

    哈哈,让我把错误给找出来了,c++  31ms,(*^__^*) 嘻嘻……有点成就感,也有点烦闷,单步调试终于把错误搞出来了,可是这个是递归诶,单步调试,我的时间啊。。。。~~~~(>_<)~~~~ 

    错误是:合并时应该将孩子像父亲这方合并。。。。。。否则会是错误答案,把错误找出来后就知道为什么了。。。画画图就知道了。。。

    View Code
      1 #include <cstdio>
    2 #include <cstring>
    3
    4 const int maxn = 40010;
    5
    6 struct node
    7 {
    8 int tag;
    9 int w;
    10 struct node *next;
    11 }*temp;
    12
    13 struct head
    14 {
    15 struct node *next;
    16 };
    17 head pnt[maxn];
    18 head que[maxn];
    19 bool vis[maxn];
    20 int ans[maxn];
    21 int f[maxn];
    22 int dis[maxn];
    23 int n,m;
    24
    25 void init()
    26 {
    27 for(int i = 0;i <= n;i ++)
    28 {
    29 f[i] = i;
    30 pnt[i].next = NULL;
    31 que[i].next = NULL;
    32 }
    33 memset(vis,false,sizeof(vis));
    34 memset(ans,0,sizeof(ans));
    35 memset(dis,0,sizeof(dis));
    36 }
    37
    38 void insert_edge(int a,int b,int w)
    39 {
    40 temp = new node;
    41 temp -> tag = b;
    42 temp -> w = w;
    43 temp -> next = pnt[a].next;
    44 pnt[a].next = temp;
    45 }
    46
    47 void insert_ans(int a,int b,int l)
    48 {
    49 node *temp = new node;
    50 temp -> tag = b;
    51 temp -> w = l;
    52 temp ->next = que[a].next;
    53 que[a].next = temp;
    54 }
    55
    56 int find(int x)
    57 {
    58 if(x == f[x])
    59 return x;
    60 f[x] = find(f[x]);
    61 return f[x];
    62 }
    63
    64 void join(int x,int y)//一定要注意这里的合并哈
    65 {
    66 int fx = find(x);
    67 int fy = find(y);
    68 if(fx == fy)
    69 return ;
    70
    71 f[fy] = fx;
    72 }
    73
    74 void lca(int x,int d)
    75 {
    76 dis[x] = d;
    77 vis[x] = true;
    78 for(node *t = que[x].next;t != NULL;t = t ->next)
    79 {
    80 if(vis[t -> tag])
    81 {
    82 ans[t -> w] = dis[x] + dis[t -> tag] - 2 * dis[find(t->tag)];
    83 }
    84 }
    85
    86 for(node *t = pnt[x].next;t !=NULL;t = t -> next)
    87 {
    88 if(!vis[t -> tag])
    89 {
    90 lca(t -> tag,d + t -> w);
    91 join(x,t -> tag);
    92 }
    93 }
    94 }
    95 int main()
    96 {
    97 int cas;
    98 scanf("%d",&cas);
    99 while(cas --)
    100 {
    101 scanf("%d%d",&n,&m);
    102 init();
    103 int a,b,w;
    104 for(int i = 1;i < n;i ++)
    105 {
    106 scanf("%d%d%d",&a,&b,&w);
    107 insert_edge(a,b,w);
    108 insert_edge(b,a,w);
    109 }
    110
    111 for(int i = 1;i <= m;i ++)
    112 {
    113 scanf("%d%d",&a,&b);
    114 insert_ans(a,b,i);//这里有点小技巧。。。将顺序也一并存储,为后面处理做好准备,主要是要按输入顺序输出答案。。。
    115 insert_ans(b,a,i);
    116 }
    117
    118 lca(1,0);
    119
    120 for(int i = 1;i <= m;i ++)
    121 {
    122 printf("%d\n",ans[i]);
    123 }
    124 }
    125
    126 return 0;
    127 }

    还可以用入度来弄这一题,不过,要46ms,因为主函数里多了一层循环。。。。。。其他的都没有变就多了一个记录入度的数组,并查找入度为0的点。。。。。。

    View Code
      1 #include <cstdio>
    2 #include <cstring>
    3
    4 const int maxn = 40010;
    5
    6 struct node
    7 {
    8 int tag;
    9 int w;
    10 struct node *next;
    11 }*temp;
    12
    13 struct head
    14 {
    15 struct node *next;
    16 };
    17 head pnt[maxn];
    18 head que[maxn];
    19 bool vis[maxn];
    20 int ans[maxn];
    21 int f[maxn];
    22 int dis[maxn];
    23 int n,m;
    24 int ind[maxn];
    25
    26 void init()
    27 {
    28 for(int i = 0;i <= n;i ++)
    29 {
    30 f[i] = i;
    31 pnt[i].next = NULL;
    32 que[i].next = NULL;
    33 }
    34 memset(vis,false,sizeof(vis));
    35 memset(ans,0,sizeof(ans));
    36 memset(ind,0,sizeof(ind));
    37 memset(dis,0,sizeof(dis));
    38 }
    39
    40 void insert_edge(int a,int b,int w)
    41 {
    42 temp = new node;
    43 temp -> tag = b;
    44 temp -> w = w;
    45 temp -> next = pnt[a].next;
    46 pnt[a].next = temp;
    47 }
    48
    49 void insert_ans(int a,int b,int l)
    50 {
    51 node *temp = new node;
    52 temp -> tag = b;
    53 temp -> w = l;
    54 temp ->next = que[a].next;
    55 que[a].next = temp;
    56 }
    57
    58 int find(int x)
    59 {
    60 if(x == f[x])
    61 return x;
    62 f[x] = find(f[x]);
    63 return f[x];
    64 }
    65
    66 void join(int x,int y)
    67 {
    68 int fx = find(x);
    69 int fy = find(y);
    70 if(fx == fy)
    71 return ;
    72
    73 f[fy] = fx;
    74 }
    75
    76 void lca(int x,int d)
    77 {
    78 dis[x] = d;
    79 vis[x] = true;
    80 for(node *t = que[x].next;t != NULL;t = t ->next)
    81 {
    82 if(vis[t -> tag])
    83 {
    84 ans[t -> w] = dis[x] + dis[t -> tag] - 2 * dis[find(t->tag)];
    85 }
    86 }
    87
    88 for(node *t = pnt[x].next;t !=NULL;t = t -> next)
    89 {
    90 if(!vis[t -> tag])
    91 {
    92 lca(t -> tag,d + t -> w);
    93 join(x,t -> tag);
    94 }
    95 }
    96 }
    97 int main()
    98 {
    99 int cas;
    100 scanf("%d",&cas);
    101 while(cas --)
    102 {
    103 scanf("%d%d",&n,&m);
    104 init();
    105 int a,b,w;
    106 for(int i = 1;i < n;i ++)
    107 {
    108 scanf("%d%d%d",&a,&b,&w);
    109 insert_edge(a,b,w);
    110 ind[b] ++;
    111 //insert_edge(b,a,w);
    112 }
    113
    114 for(int i = 1;i <= m;i ++)
    115 {
    116 scanf("%d%d",&a,&b);
    117 insert_ans(a,b,i);
    118 insert_ans(b,a,i);
    119 }
    120
    121 for(int i = 1;i <= n;i ++)
    122 {
    123 if(ind[i] == 0)
    124 {
    125 lca(i,0);
    126 break;
    127 }
    128 //lca(1,0);
    129 }
    130
    131 for(int i = 1;i <= m;i ++)
    132 {
    133 printf("%d\n",ans[i]);
    134 }
    135 }
    136
    137 return 0;
    138 }




  • 相关阅读:
    Could not load file or assembly 'Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0, ...
    问题:ORA-28000: the account is locked 用户锁住了。
    oracle连接数据库报错:ORA-01034: ORACLE not available(Oracle 不存在),ORA-27101: shared memory realm does not exist
    数据抽取Sql语句
    在Eclipse中部署Maven多模块项目
    Struts 学习记录
    eclipse中git插件无法向远程仓库提交tag的问题
    goldGrid-VBA-EXCLE处理
    SqlBulkCopy效率低下原因分析
    各种奇葩小问题
  • 原文地址:https://www.cnblogs.com/Shirlies/p/2419897.html
Copyright © 2011-2022 走看看