哈哈,让我把错误给找出来了,c++ 31ms,(*^__^*) 嘻嘻……有点成就感,也有点烦闷,单步调试终于把错误搞出来了,可是这个是递归诶,单步调试,我的时间啊。。。。~~~~(>_<)~~~~
错误是:合并时应该将孩子像父亲这方合并。。。。。。否则会是错误答案,把错误找出来后就知道为什么了。。。画画图就知道了。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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的点。。。。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }