TZOJ 3659 神奇的探险之旅(有向无环每个点只能经过一次最长路dij)

描述

我们正在设计这样的一款儿童探险游戏:游戏由很多故事场景组成,每个场景中都有一个问题,游戏根据玩家的回答将进入下一场景,经过巧妙的设计,我们保证在一次“探险旅行”中,不会重复的进入任何相同的场景,因此最终探险故事将根据玩家的选择结束在某个场景中。玩家总希望能够让自己的探险之旅尽可能的长,给定故事情节布局,请判断最长能够到达多少个场景?
我们对故事的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\n",o++,dij());
43     }
44     return 0;
45 }

posted on 2018-08-31 00:44  大桃桃  阅读(441)  评论(0编辑  收藏  举报

导航