流感传播:图论,队列思想。

流感

题目描述

    学校里一共有n个学生。这n个学生里一共有m对朋友关系。
    在流感发作期,每个健康学生都要看望当天他生病的朋友(如果有的话),并在第二天被传染上疾病(除非他在免疫期内);
    每个生病的学生在第二天都会痊愈,并在这一天具有免疫性。从第三天起,看望生病的朋友将再次使他染上流感。
    初始时(第一天),只有一个学生患有流感。试问多少天后流感会自动结束。

关于输入

第一行输入两个正整数n和m。
接下来m行每行两个正整数x,y,表示编号为x的学生和编号为y的学生是一对朋友。输入数据保证每一对朋友关系只描述一次。
最后一行输入一个正整数,代表初始时患有流感的学生的编号。
n,m <= 100,000。

关于输出

输出多少天后流感会结束。
如果天数超过2,000,000,000,则视为流感不会结束,输出-1。

例子输入
4 4
1 2
2 3
3 4
2 4
1
例子输出
3
提示信息

第一天1号学生生病,2号学生访问他;
第二天2号学生生病,其它三个学生访问他,由于1号处于免疫期,未患流感;
第三天3、4号学生生病,2号学生访问他们。
第四天3、4号学生痊愈,流感结束。

解题思路

利用队列和生病天数的全局变量来控制流感的传播与感染,定义结构体来存储每个节点的朋友,当朋友生病的时间在当前节点流感时间的前2天的时候,则又将该人放入感染的队列。

代码实现
#include <bits/stdc++.h>
using namespace std;
typedef struct node{
    vector<int> friends;
    int sicktime=-1;
} node;
int main(){
    int n,m; cin>>n>>m;
    vector<node> students(n+1);
    while(m--){
        int x,y;
        cin>>x>>y;
        students[x].friends.push_back(y);
        students[y].friends.push_back(x);
    }
    queue<int> q;
    int start; cin>>start;
    q.push(start);
    students[start].sicktime=1;
    while(!q.empty()){
        int front=q.front();
        if(students[front].sicktime>2000000000){
            cout<<-1<<endl;
            return 0;
        }
        for(int i=0;i<students[front].friends.size();i++){
            int num=students[front].friends[i];
            if(students[num].sicktime==-1 ||
             students[num].sicktime<=students[front].sicktime-2){
                students[num].sicktime=students[front].sicktime+1;
                q.push(num);
             }
        }
        q.pop();
    }
    int maxtime=0;
    for(int i=1;i<=n;i++){
        if(students[i].sicktime>maxtime){
            maxtime=students[i].sicktime;
        }
    }
    cout<<maxtime<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值