HDU6777 Covid

本文介绍了一个基于优先队列和地图数据结构的病毒传播模拟算法,用于研究病毒如何在人群中传播,通过跟踪个体在不同时间点的位置,判断病毒的传播路径,并最终确定受感染人群。该算法适用于大规模人群的疫情模拟,帮助科学家理解并控制疫情。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem Description

科学家小沃沃在研究病毒传播的规律,从而控制疫情。
有n个人,编号分别为1,2,…,n。 我们用荧光粉代替病毒,编号为1的人,在第0时刻涂上了荧光粉,剩下的人在第0时刻没有涂。
对于第i个人,我们知道这个人在哪些时刻出现在了哪些地方。
如果时刻t,某个人和身体上有荧光粉的人,出现在了同一地点,那么从时刻t以后,这个人也会沾上荧光粉。
从小到大输出实验结束后身体上有荧光粉的人的编号。

Input

第一行一个整数T(1 <T< 20)表示T组数据。
对于每组数据,第一行一个整数n(1 <n< 20000)表示n个人。
对于第i个人,第一行输入一个整数len[i](1 < len[i] < 100)表示这个人的活动轨迹。
接下来len[i]行,每行输入两个整数t,p(1 <t< 100,1 <p≤10)表示这个人t时刻出现在了p位置,保证t按严格递增的顺序给出。
除了这len[i] 个时刻,这个人都呆在家里,或者换句话说,他/她不在任何位置。
保证len[1] + len[2]+… +len[n] < 200000。

Output

对于每组数据输出一行,表示所有患者的编号。按编号从小到大输出。

Sample Input

2
4
2
11
22
3
22
33
44
1
44
1
21
3
3
11
31
61
3
41
51
61
1
51

Sample Output

123
12

样例解释 Case 1: 第2时刻,位置2,1与2相遇,2沾上了。 第4时刻,位置4,2与3相遇,3沾上了。 Source
2020年百度之星:程序设计大赛-初赛二

#include<bits/stdc++.h>
using namespace std;
int len[20001];
bool b[20001];//标记

typedef struct A
{
    int t;
    int p;
}tp;

bool operator > (tp a1, tp a2){
	return a1.t > a2.t;
}
vector<tp> ve[20001];
priority_queue<tp,vector<tp>,greater<tp> > q;
map<int,int> mp;
vector<int> vec[1001];

int main() {
	int T,n;
	scanf("%d",&T);
	while(T--){
        scanf("%d",&n);
        int tmp = 1;
        mp.clear();
        for(int i = 1;i <=1000;i++) vec[i].clear();
        for(int i =1;i<=n;i++) ve[i].clear();
        while(!q.empty()) q.pop();
        memset(b,false,sizeof(b));
        for(int i = 1;i <= n;i++){
            scanf("%d",&len[i]);
            for(int t,p,j = 1;j <= len[i];j++){
                scanf("%d %d",&t,&p);

                ve[i].push_back(tp{t,p});
                int hah = t*100+p;
                if(mp.end() == mp.find(hah)){
                    mp[hah]=tmp++;
                }
                vec[mp[hah]].push_back(i);
            }
        }
        for(tp pp:ve[1]){
            q.push(pp);
        }

        b[1] = true;
        while(!q.empty()){
           tp pp = q.top();
            q.pop();
            int t = pp.t,pos = pp.p;
            int hah = t*100+pos;
            for(int v:vec[mp[hah]]){
                if(b[v] == true) continue;
                else {
                    for(tp pc:ve[v]){
                        if(pc.t > t)
                            q.push(pc);
                    }
                }
                b[v] =true;
            }
        }
        printf("1");
        for(int i = 2;i <= n;i++){
            if(b[i] == true) printf(" %d",i);
        }
        printf("\n");
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值