链式前向星-学习笔记

模板:

数据结构:

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;
    
}

 

posted @ 2018-03-11 14:22  TQCAI  阅读(429)  评论(0编辑  收藏  举报