蓝桥杯-单链表-网络寻路
- 单链表基本操作
- 操作一:向链表头插入一个数
- 操作二:在第 k个插入的数后插入一个数
- 操作三:删除第 k个插入的数后面的一个数;
- P8605 [蓝桥杯 2013 国 AC] 网络寻路
单链表基本操作
初始化有关操作
// head 表示头结点的下标
// e[i] 表示节点i的值
// ne[i] 表示节点i的next指针是多少
// idx 存储当前已经用到了哪个点,这个点的节点
int head, e[N], ne[N], idx;
// 初始化
void init()
{
head = -1;
idx = 0;
}
操作一:向链表头插入一个数
// 将x插到头结点
void add_to_head(int x)
{
e[idx] = x;取value
ne[idx] = head,;将idx指向head“指向的节点”
head = idx;将head指向idx
idx++;下一个idx(工具人)
}
这里的head可以比较令人费解,head表示的是头节点的下标,其本身不是节点。指向head指向的节点其实就是指向原来的头节点,这样新节点就取而代之成为新的头节点。
操作二:在第 k个插入的数后插入一个数
// 将x插到下标是k的点后面
void add(int k, int x)
{
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx ;
idx++;
}
操作三:删除第 k个插入的数后面的一个数;
// 将下标是k的点后面的点删掉
void remove(int k)
{
ne[k] = ne[ne[k]];
}
P8605 [蓝桥杯 2013 国 AC] 网络寻路
思路:
- 以第一组数据为例,先将给定的三组节点连起来,且可以双向通讯。
- 结果就是 1->2; 2->1; 2->3; 3->2; 1->3; 3->1; 然后我们就可以去拼接了。
- 用dfs去枚举子节点,且记录父节点不能重复(题目要求的中间节点必须不同)
说明:
1->2->1 不会出现,直接continue到下一个。
1->2->3->1 就是合法的。
解释:
题目的中间节点不重复,转移两个位置只是针对4个节点。节点很多也去其中4个。
题目的中间节点不合法的情况必然会出现1->2->1这种与父节点相同的,因此只要引入父节点就不会可以保证合法。 - 如果cnt==4 那就方案加1。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
int h[N],e[N],ne[N];
int ans;
int idx;
void add(int a,int b)//去连接节点
{
e[idx]=b;
ne[idx]=h[a];
h[a]=idx;
idx++;
}
void dfs(int x,int fa,int cnt)//枚举子节点
{
if(cnt==4)
{
ans++;
return;
}
for(int i=h[x];i!=-1;i=ne[i])
{
int j=e[i];
if(j==fa)continue;
dfs(j,x,cnt+1);
}
return ;
}
signed main()
{
memset(h,-1,sizeof h);
int n,m;
cin>>n>>m;
for(int i=0;i<m;i++)
{
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
//i为当前节点,对于第一次就是起点;fa为父节点;cnt为当前节点个数
for(int i=1;i<=n;i++) //枚举起点
{
dfs(i,-1,1);
}
cout<<ans;
return 0;
}