美团笔试-病毒传播
描述
給出一個圖G(V,E),圖上有n個點,m條邊,所有的邊都是無向邊。
最開始,也就是第0天的時候,這n個點中有一個點v感染了病毒,之后的每一天,凡是感染病毒的點都會向它的鄰居點傳播病毒。經過了t天之后,得到了感染病毒的點集S。要求找出第0天感染病毒的點v。如果v有很多不同的答案,把它們都找出來。
輸入描述:
第一行兩個數n,m,接下來有m行,每行兩個數u,v,表示點u,v之間有一條無向邊。接下來一行兩個數k,t,其中k表示集合S的大小。最后一行k個數,集合S中的元素。輸入的圖可能有自環和重邊,輸入保證S中的數互不相同。(1≤n≤103,0≤m≤103,1≤t≤109,1≤u,v,k≤n,S中所有元素在區間[1,n])
輸出描述:
輸出一行,如果不存在這樣的v,輸出-1。
否則輸出所有可能的v,按照從小到大的順序輸出,數字之間用空格隔開,不要在行末輸出多余的空格。
示例1
輸入:
4 3 3 2 1 2 1 4 3 2 4 2 1輸出:
4說明:
第0天,第1天,第2天感染病毒的點如圖?
解題思路:
這道題是一道典型的圖題目,可以利用鄰接表構建圖,二維數組存儲,然后利用一個數組標記那些被感染的點;題目要求從小到大輸出可能的起始點,然后根據感染點以及廣度優先搜索(bfs)判斷在t時間內能否導致感染相同的點即可。
#include <bits/stdc++.h> using namespace std;/*以x為起點傳播t天的結果與實際(題目給的結果)比較*/ bool bfs(vector<vector<int>>& adj,int x,int t,vector<int>& infected){/*每個點被感染需要的時間*/vector<int> cost(infected.size()+1,-1);queue<int> q;cost[x]=0;//起始時間為0q.push(x);while(!q.empty()){auto u=q.front();q.pop();if(cost[u]>=t) break;for(auto& v:adj[u]){if(cost[v]==-1){cost[v]=cost[u]+1;q.push(v);}}}for(int i=1;i<=infected.size();++i){if(!infected[i]&&cost[i]!=-1) return false;if(infected[i]&&cost[i]==-1) return false;}return true; }int main(int argc,char* argv[]){int n,m,k,t;cin>>n>>m;vector<vector<int>> adj(n+1);for(int i=0;i<m;++i){//建立鄰接表int u,v;cin>>u>>v;adj[u].push_back(v);adj[v].push_back(u);}vector<int> infected(n+1,0);cin>>k>>t;for(int i=0;i<k;++i){//記錄感染的int v;cin>>v;infected[v]=1;//從小到大}vector<int> res;for(int i=1;i<=n;++i){if(infected[i]&&bfs(adj,i,t,infected)){//只有感染的才需要檢測res.push_back(i);}}for(auto& r:res)printf("%d ",r);if(res.empty())printf("%d",-1);cout<<endl;return 0; }總結
- 上一篇: 记忆单元属于计算机硬件系统吗,计算机基础
- 下一篇: 方正字体下载2