链式前向星-学习笔记
模板:
数据结构:
int head[LEN]; //记录源点u在mp中第一个地址i=head[u] 调用完之后就可以用mp[i]访问边表mp int cnt=0; //边表下标,随着数据的录入而扩张 struct edge{ //边 int to,next,w; }; edge mp[LEN]; //边表
加边函数:
void add(int u,int v,int w){ //增加边 mp[cnt].to=v; mp[cnt].w=w; mp[cnt].next=head[u]; //指向源点u所构成的静态链表的头结点。如果是首次构造链,head[u]=-1 ,相当于NULL head[u]=cnt++; //更新当前地址 }
注意:加边之前用fill给head数组初始化复制为-1(0xFFFFFFFF)
实例:
● 用链式前向星解决DFS
OJ链接:Battle Over Cities
(注意:因为记录的是边表,所以不要按顶点大小来开数据,最好按顶点大小N的平方,或者指定的边的数据M来开数据)
AC代码:
#include <stdio.h> #include <memory.h> #include <math.h> #include <cstring> #include <vector> #include <set> #include <stack> #include <queue> #include <algorithm> #include <map> #define I scanf #define OL puts #define O printf #define F(a,b,c) for(a=b;a<c;a++) #define FF(a,b) for(a=0;a<b;a++) #define FG(a,b) for(a=b-1;a>=0;a--) #define LEN 1000000 #define MAX 1<<30 #define V vector<int> using namespace std; int head[LEN]; //记录源点u在mp中第一个地址i=head[u] 调用完之后就可以用mp[i]访问边表mp int cnt=0; //边表下标,随着数据的录入而扩张 struct edge{ //边 int to,next,w; }; edge mp[LEN]; //边表 void add(int u,int v,int w){ //增加边 mp[cnt].to=v; mp[cnt].w=w; mp[cnt].next=head[u]; //指向源点u所构成的静态链表的头结点。如果是首次构造链,head[u]=-1 ,相当于NULL head[u]=cnt++; //更新当前地址 } int vis[LEN]; int bk; void dfs(int s){ vis[s]=1; int i; for(i=head[s];~i;i=mp[i].next){ int to=mp[i].to; if(!vis[to] && to!=bk) dfs(to); } } int main(){ // freopen("battle over city.txt","r",stdin); fill(head,head+LEN,-1); int n,m,k,a,b,i; I("%d%d%d",&n,&m,&k); while(m--){ I("%d%d",&a,&b); add(a,b,1); add(b,a,1); } while(k--){ I("%d",&bk); memset(vis,0,sizeof vis); int ans=0; F(i,1,n+1) if(i!=bk && !vis[i]){ dfs(i); ans++; } O("%d\n",ans-1); } return 0; }
● 用链式前向星解决BFS
OJ链接:Forwards on Weibo
AC代码:
#include <stdio.h> #include <memory.h> #include <math.h> #include <cstring> #include <vector> #include <set> #include <stack> #include <queue> #include <algorithm> #include <map> #define I scanf #define OL puts #define O printf #define F(a,b,c) for(a=b;a<c;a++) #define FF(a,b) for(a=0;a<b;a++) #define FG(a,b) for(a=b-1;a>=0;a--) #define LEN 100000 #define MAX 1<<30 #define V vector<int> using namespace std; int head[LEN]; int vis[LEN]; int cnt=0; struct edge{ int to,w,next; }; edge mp[LEN]; void add(int u,int v,int w){ mp[cnt].to=v; mp[cnt].w=w; mp[cnt].next=head[u]; head[u]=cnt++; } int main(){ // freopen("Forwards on Weibo.txt","r",stdin); int N,L,M,K,i,j; fill(head,head+LEN,-1); I("%d%d",&N,&L); F(i,1,N+1){ I("%d",&M); while(M--){ I("%d",&j); add(j,i,1); } } I("%d",&K); while(K--){ I("%d",&i); memset(vis,0,sizeof vis); queue<int> q; q.push(i); int lev=0,cnt=0; while(!q.empty()){ int sz=q.size(); while(sz--){ int u=q.front(); q.pop(); vis[u]=1; for(j=head[u];~j;j=mp[j].next){ int to=mp[j].to; if(!vis[to]){ vis[to]=1; q.push(to); cnt++; } } } lev++; if(lev>=L) break; } O("%d\n",cnt); } return 0; }