前向星是一种特殊的边集数组。
不同于邻接表和邻接矩阵对顶点的处理,前向星存图处理的是边与边的关系。
int cnt; //记录边的编号
int head[maxn]; //head[u]表示上一个以u为起点的边的编号,初始化-1
struct st //储存边的信息
{
int to; //边的终点
int w; //边的权值
int next; //下一个同起点边的编号
} edge[maxn];这里再解释一下head数组和edge数组:
edge[i]并不是表示第i个顶点,而是编号为i的边,edge结构体不包含边的起点,但包含了与该边同起点的边的编号。
head[u]记录最后一条以u为起点的边的编号;
若head[u]==-1,则说明没有以u为起点的边;
若head[u]!=1,则可以找到最后一条边的编号v,经由edge[v].next找到下一条边,直到next==-1。
inline void add(int u,int v,int w) //加边
{
edge[++cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
}
void dfs(int u,int pre)
{
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v==pre) continue;
dfs(v,u);
}
}以下是【每日一题】 Shortest Path 的ac代码:
题目:https://ac.nowcoder.com/acm/problem/13886
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cctype>
#include <functional>
#include <string>
#include <cstring>
#include <sstream>
#include <deque>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> Q;
const int inf1=2e9+9;
const ll inf2=8e18+9;
const ll mol=998244353;
const int maxn=2e4+9;
const int maxx=1e9+9;
int n;
ll ans;
int cnt,head[maxn];
struct st{int to,w,next;} edge[maxn];
inline void add(int u,int v,int w)
{
edge[++cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
}
int dfs(int u,int pre)
{
int cnt_=1;
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(v==pre) continue;
if(dfs(v,u))
{
cnt_++;
ans+=edge[i].w;
}
}
return cnt_%2;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
cnt=0;
memset(head,-1,sizeof head);
scanf("%d",&n);
for(int i=0;i<n-1;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
ans=0;
dfs(1,0);
printf("%lld\n",ans);
}
}
当中要注意的是,对于无向边,每条边要储存两次,所以head和edge都要开原来的原来的两倍大小。

京公网安备 11010502036488号