标签:style blog http color os io for art
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\n",spfa(t1,t2)); 71 } 72 } 73 }
题解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\n",ans[i]); 117 } 118 } 119 return 0; 120 }
标签:style blog http color os io for art
原文地址:http://www.cnblogs.com/chujian123/p/3871430.html