描述
我们正在设计这样的一款儿童探险游戏:游戏由很多故事场景组成,每个场景中都有一个问题,游戏根据玩家的回答将进入下一场景,经过巧妙的设计,我们保证在一次“探险旅行”中,不会重复的进入任何相同的场景,因此最终探险故事将根据玩家的选择结束在某个场景中。玩家总希望能够让自己的探险之旅尽可能的长,给定故事情节布局,请判断最长能够到达多少个场景?
我们对故事的m个场景进行编号(1~m),并且每次都是从编号为1开始探险之旅。
输入
输入数据有多组,每组数据的第一行位一个正整数n,表示数据的组数。
每组数据的第一行为一个正整数m(1<m<1000),表示故事场景的总数,接下来有m行,第i行描述了第i个场景的信息,包括3种情况:
(1)如果该行包含1个正整数j,则表示由第i个故事场景只能到达第j个场景;
(2)如果该行包含2个正整数j和k,则表示由第i个故事场景可以到达第j或者k个场景;
(3)如果该行包含1个字符串“ENDING”,表示故事在第i个场景结束;
输出
每组数据输出格式如下:
Case #x: y
x为测试数据编号,从1开始计算,y为一个整数,表示最多能经过的场景数量。
样例输入
2
3
2 3
ENDING
ENDING
5
4 5
ENDING
2
3
4
样例输出
Case #1: 2
Case #2: 5
题意
给你一个有向无环图,求每个点只能经过一次最长路
题解
因为是有向无环图,所以可以每条边权值设为-1,跑一遍dij
代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=1005; 5 int T,sum,n,o=1,d[maxn]; 6 vector< vector<int> >G(maxn); 7 int dij() 8 { 9 memset(d,0,sizeof d); 10 queue<int>q; 11 q.push(1); 12 while(!q.empty()) 13 { 14 int u=q.front();q.pop(); 15 for(auto v:G[u]) 16 { 17 if(d[v]>d[u]-1) 18 { 19 d[v]=d[u]-1; 20 q.push(v); 21 } 22 } 23 } 24 return *min_element(d+1,d+1+n)*-1+1; 25 } 26 int main() 27 { 28 string s; 29 cin>>T; 30 while(T--) 31 { 32 cin>>n; 33 cin.get(); 34 for(int i=1;i<=n;i++) 35 { 36 G[i].clear(); 37 getline(cin,s); 38 if(s[0]=='E')continue; 39 stringstream ss(s); 40 while(ss>>sum)G[i].push_back(sum); 41 } 42 printf("Case #%d: %d ",o++,dij()); 43 } 44 return 0; 45 }