之前用vector数组代替邻接表做了几道题 像我之前做的这个: [病毒溯源](https://blog.youkuaiyun.com/weixin_46177831/article/details/123626603?spm=1001.2014.3001.5501)
但是最近遇到一个题目,是不能用普通的vector数组来替代邻接表的,因为它加上了权重,因此 还是得学习一下邻接表的使用。用邻接表的方法再做一下这几道题。
有一棵 n (1 <= n <= 100000) 个点的树。树上的边有正边权 ( 1 <= 边权 <= 10000)。
以s (1 <= s <= n)号点为树根,求到t (1 <= t <= n)号点的边权之和。
输入格式:
第一行三个正整数n,s,t。
接下来n-1行,每行三个正整数a,b,w(表示点a和点b之间有一条边权为w的无向边)。
输出格式:
输出从点s到点t的边权和。
输入样例:
4 1 4
1 2 3
2 3 4
3 4 5
输出样例:
12
源代码:
#include <iostream>
using namespace std;
const int MAXn=100000+10;
const int MAXm=200000+10;
int n,s,t,edge,head[MAXn],vis[MAXn],len;
struct list{
int to;
int w;
int nxt;
}e[MAXm];
void add_edge(int u,int v,int w){
e[++edge].to=v;
e[edge].nxt=head[u];
e[edge].w=w;
head[u]=edge;
}
void dfs(int node,int cnt){
if(node==t){
len=cnt;
return;
}
for(int i=head[node];i;i=e[i].nxt){
if(!vis[e[i].to]){
vis[e[i].to]=1;
dfs(e[i].to,cnt+e[i].w);
}
}
}
int main()
{
cin>>n>>s>>t;
int u,v,w;
for(int i=0;i<n-1;++i){
cin>>u>>v>>w;
add_edge(u,v,w);
add_edge(v,u,w);
}
vis[s]=true;
dfs(s,0);
cout<<len;
return 0;
}
病毒溯源:
#include <iostream>
using namespace std;
const int MAXn=10000+10;
const int MAXm=200000+20;
int n,maxdeep;//记录最大链长
int ans[MAXn],temp[MAXn];//记录答案序列 及辅助序列
int sou[MAXn];//寻找病毒源头
int edge;//记录是第几条边
int head[MAXn];//每个点的最后一条边
struct list{//存储所有边
int to;
int nxt;
}e[MAXm];
void add_edge(int u,int v){//建边函数
e[++edge].to=v;
e[edge].nxt=head[u];
head[u]=edge;
}
bool judge(int deep){
for(int i=1;i<=deep;++i){
if(temp[i]>ans[i]) return false;
else if(temp[i]<ans[i]) return true;
}
}
void dfs(int node,int deep){
temp[deep]=node;
if(head[node]==0){//一条链的结尾
if(deep>maxdeep){
maxdeep=deep;
for(int j=1;j<=deep;++j)
ans[j]=temp[j];
}
else if(deep==maxdeep){
if(judge(deep)){
for(int j=1;j<=deep;++j)
ans[j]=temp[j];
}
}
return;
}
for(int i=head[node];i;i=e[i].nxt){
dfs(e[i].to,deep+1);
}
}
int main()
{
cin>>n;
for(int u=0;u<n;++u){
int k;
cin>>k;
for(int i=0;i<k;++i){
int v;
cin>>v;
add_edge(u,v);
sou[v]=1;
// add_edge(v,u);
}
}
int root;
for(int i=0;i<n;++i){
if(sou[i]==0){
root=i;
break;
}
}
dfs(root,1);
cout<<maxdeep<<endl;
for(int i=1;i<maxdeep;++i)
cout<<ans[i]<<" ";
cout<<ans[maxdeep];
return 0;
}