生化危机 邻接表存图+BFS

生化危机

发布时间: 2015年10月10日 18:05   时间限制: 1000ms   内存限制: 256M

描述

X博士想造福人类, 研发一种可以再生肢体的药物, 可是很不幸......研究失败了, 他在蜥蜴身上实验的时候, 蜥蜴发生了变异, 更糟糕的是, 蜥蜴逃出了生化实验室.

恐怖的事情发生了, 疫情以X博士所在的城市为中心向四周扩散开, 最终, 整个地球上的城市都被感染了.假设整个地球一共有N个城市, 这N个城市是连通的, 有N-1条通道把他们连接起来.病毒会以一座城市为中心,在一天的时间内, 会把和他相连的周围的所有城市感染. 那么, 多少天的时间, 整个地球的城市都感染呢?

输入

第一行输入一个T(T <= 50), 表示一共有T组测试数据.
每组数据第一行两个数n, k. n表示有n(2 <= n <= 10000)个城市, 代表城市1-n, k是X博士所在的城市.
接下来n-1行, 每行有两个数u, v, 表示城市u和v之间有一条通道.

输出

每组数据第一行输出第一个数 x , 表示整个地球感染需要x天.
接下来 x 个数, 第i个数表示第i天感染了城市的数量.
(注意, 每组数据第二行每个数据后边都有一个空格)

样例输入1 复制

2
3 1
1 2
2 3
3 2
1 2
2 3

样例输出1

3
1 1 1
2
1 2


一道邻接表存图+BFS的好题。重点是邻接表,vector使用链式存储,适用于稀疏图,存多少点开多少点,避免了邻接矩阵存图导致的空间浪费,而且减少了无谓的枚举,也能大大提高时间效率。邻接表存储原理:可以把vector的v数组实际可以看成一个二维数组v[][],第一个下标表示u->v边的左端点u,第二个下标是以u出度边的个数,元素值代表v。当然这只适用于各边权值相同的情况(对这道题来说已经足够,带权边的图可使用struct)。记录BFS扩展次数,每扩展一次,记录下感染数量即可。
#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;

struct Node{
    int x,s;
}node;

int main()
{
    int t,n,k,x,y,tx,cc,c,i;
    int a[10005],b[10005];
    queue<Node> q;
    vector<int> v[10005];
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&k);
        for(i=1;i<=n;i++){
            v[i].clear();
        }
        for(i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            v[x].push_back(y);
            v[y].push_back(x);
        }
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        b[k]=1;
        node.x=k;
        node.s=1;
        q.push(node);
        cc=0;c=1;
        while(q.size()){
            if(a[q.front().s]==0){
                a[++cc]=c;
                c=0;
            }
            for(i=0;i<v[q.front().x].size();i++){   //切记从0开始
                tx=v[q.front().x][i];
                if(b[tx]==0){
                    c++;
                    b[tx]=1;
                    node.x=tx;
                    node.s=q.front().s+1;
                    q.push(node);
                }
            }
            q.pop();
        }
        printf("%d\n",cc);
        for(i=1;i<=cc;i++){
            printf("%d ",a[i]);
        }
        printf("\n");
    }
    return 0;
}
时间: 2024-10-27 19:37:12

生化危机 邻接表存图+BFS的相关文章

HDU 4857 逃生(拓扑排序逆向+邻接表存图)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 题目: Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处. 负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,

邻接表存图

邻接表也叫边表,也是OI中常用的存图方法之一,以后所有的图论算法 我都打算用这个写,具体也不难理解. 这种存图方式是用了N(点的个数)个链表将整个图串联起来,串联方式 便是那个first数组. 我们首先定义了一个结构体,结构体一共有三个参数,终点,权值,这个边 的下一条边. 具体操作:每当输入一条边的数据时,我们将这组数据送进加边函数(也可以 直接写在main函数中的for循环里)cnt是边数,是一个给每条边编号的工具 我们存一下第cnt条边的终点权值以及与cnt相关的下一条边,这个串联是通过

ACM模板——链式前向星&amp;&amp;邻接表存图

邻接表待补充 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define MAXN 100501 4 struct NODE{ 5 int w; 6 int e; 7 int next; //next[i]表示与第i条边同起点的上一条边的储存位置 8 }edge[MAXN]; 9 int cnt; 10 int head[MAXN]; 11 void add(int u,int v,int w){ 12 edge[cnt].w=w; 1

SDOI2010_大陆争霸(邻接表存图)

题目描述 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国.两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光明和永恒的神斯普林·布拉泽. 幻想历 8012年 1月,杰森国正式宣布曾·布拉泽是他们唯一信仰的神,同 时开始迫害在杰森国的信仰斯普林·布拉泽的克里斯国教徒. 幻想历 8012年 3月2日,位于杰森国东部小镇神谕镇的克里斯国教徒发动 起义. 幻想历 8012年 3月7日,神谕镇的起义被杰森国大军以残酷手段镇压.

PTA 邻接表存储图的广度优先遍历(20 分)

6-2 邻接表存储图的广度优先遍历(20 分) 试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ); 其中LGraph是邻接表存储的图,定义如下: /* 邻接点的定义 */ typedef struct AdjVNode *PtrToAdjVNode; struct AdjVNode{ Vertex AdjV; /* 邻接点下标 */ PtrToAdjVNode Next; /*

6-1 邻接表存储图的广度优先遍历 (20 分)

6-1 邻接表存储图的广度优先遍历 (20 分) 试实现邻接表存储图的广度优先遍历. 函数接口定义: void BFS ( LGraph Graph, Vertex S, void (*Visit)(Vertex) ); 其中LGraph是邻接表存储的图,定义如下: /* 邻接点的定义 */ typedef struct AdjVNode *PtrToAdjVNode; struct AdjVNode{ Vertex AdjV; /* 邻接点下标 */ PtrToAdjVNode Next; /

hdu 2647 (拓扑排序 邻接表建图的模板) Reward

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2647 老板给员工发工资,每个人的基本工资都是888,然后还有奖金,然后员工之间有矛盾,有的员工希望比某员工的奖金多,老板满足了所以员工的这种心思,而且老板下午发的总工资最少,问最少是多少?比如 a b 表示a的工资比b要高(高一块钱),当出现a b   b c   c a这种环的时候输出-1 拓扑排序http://www.cnblogs.com/tonghao/p/4721072.html 小指向大

基于邻接表的图建立(有向图+无向图)

图的表示(建立)有两种方法: ①邻接矩阵:A(i,j)=1表示i,j存在一条边,空间复杂度O(n^2),稠密图 ②邻接表:只记录存在的边,Vector+List的数据结构,稀疏图 邻接矩阵的图建立这里不做赘述,接下来我们看一下邻接表的图建立: <1>有向图 注意理解头插入节点的过程 int n,m;//n表示城镇个数,m表示道路条数</span> struct LinkNode//列表节点 { int vex; //邻接的结点在数组中的编号 LinkNode* next; }; s

邻接矩阵(以顶点为中心),比较稀疏时,采用邻接表;图的两种遍历(邻接矩阵实现)

对于边比较稠密的图,可以采用邻接矩阵(以顶点为中心)的方式表示,而边比较稀疏时,采用邻接表的结构更合适.两种都不能直观表达哪两个点相连或者最短路径是什么. 深度优先遍历类似于树的先根序遍历.与树不同的是,它需要对已经访问过的节点添加标记以免被重复遍历. public class Depth { /** * 对k号节点深度遍历 * @param a * @param color * @param k 节点 */ public static void depthTraversal(int[][] a