流感
题目描述
学校里一共有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;
}