1. 程式人生 > 其它 >L2-2 病毒溯源 (25 分)

L2-2 病毒溯源 (25 分)

   

病毒容易發生變異。某種病毒可以通過突變產生若干變異的毒株,而這些變異的病毒又可能被誘發突變產生第二代變異,如此繼續不斷變化。

現給定一些病毒之間的變異關係,要求你找出其中最長的一條變異鏈。

在此假設給出的變異都是由突變引起的,不考慮複雜的基因重組變異問題 —— 即每一種病毒都是由唯一的一種病毒突變而來,並且不存在迴圈變異的情況。

輸入格式:

輸入在第一行中給出一個正整數 N(104),即病毒種類的總數。於是我們將所有病毒從 0 到 N1 進行編號。

隨後 N 行,每行按以下格式描述一種病毒的變異情況:

k 變異株1 …… 變異株k
 

其中 k 是該病毒產生的變異毒株的種類數,後面跟著每種變異株的編號。第 i 行對應編號為 i 的病毒(0i<N)。題目保證病毒源頭有且僅有一個。

輸出格式:

首先輸出從源頭開始最長變異鏈的長度。

在第二行中輸出從源頭開始最長的一條變異鏈,編號間以 1 個空格分隔,行首尾不得有多餘空格。如果最長鏈不唯一,則輸出最小序列。

注:我們稱序列 { a1,,an } 比序列 { b1,,bn } “小”,如果存在 1kn 滿足 ai=bi 對所有 i<k 成立,且 ak<bk

輸入樣例:

10
3 6 4 8
0
0
0
2 5 9
0
1 7
1 2
0
2 3 1
 

輸出樣例:

4
0 4 9 1


#include <bits/stdc++.h>
using namespace std;

#define
MAX 10001 vector<int> v[MAX]; //鄰接表 int t[MAX]; //標記陣列 vector<int>result; //存結果 void dfs(int index, vector<int> p) { if (p.size() > result.size()) { result.clear(); result = p; } for (int i = 0; i < v[index].size(); i++) { p.push_back(v[index][i]); dfs(v[index][i], p); p.pop_back(); } }
int main() { int n; cin >> n; for (int i = 0; i < n; i++) { int k, x; cin >> k; while (k--) { cin >> x; v[i].push_back(x); t[x] = 1; } if (v[i].size()) sort(v[i].begin(), v[i].end()); } for (int i = 0; i < n; i++) { if (!t[i]) { vector<int>p; p.push_back(i); dfs(i, p); break; } } cout << result.size() << endl; for (int i = 0; i < result.size(); i++) { if (i) cout << " " << result[i]; else cout << result[i]; } return 0; }