题意说的是人生的各个节点,有单向边连接并构成图,且不会形成环。每条边的权重x代表可以学到x个知识。说一个人从节点0出发,每走到一个节点,只能预见到与之相连的节点及其权重x,而且可以确定每次选得这些权重中最大的那个。最后输出能学到的最多的知识,以及终点节点的编号。
题目也很简单,因为题意已经很清晰了,就是贪心法每次都取局部最优,从节点0开始走一遍就出结果了。
python版本AC代码
testcase = int(input())
for k in range(testcase+1):
if k == 0:
continue
dropenter = input()
n,m = map(int,input().split())
s = list(map(int,input().split()))
Glist = [[] for i in range(n)]
for i in range(m):
a,b = map(int,input().split())
Glist[a].append(b)
now = maxsum = 0
while(True):
to = 0
maxt = 0
sz = len(Glist[now])
if sz == 0:
break
for j in range(sz):
if s[Glist[now][j]] > maxt:
maxt = s[Glist[now][j]]
to = Glist[now][j]
maxsum += maxt
now = to
print("Case %d: %d %d"%(k,maxsum,now))
C++版本AC代码
#include <iostream>
#include<cstdio>
#include<vector>
using namespace std;
//#define ZANGFONG
int s[110];
vector<int> G[110];
int main()
{
#ifdef ZANGFONG
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif // ZANGFONG
int testcase;
int i,j,k,n,m,a,b;
int sz,sum, now, to,mx;
scanf("%d\n",&testcase);
for(k = 1; k <= testcase; k++)
{
scanf("%d%d\n",&n,&m);
for(i = 0; i < n; i++)
{
scanf("%d",&s[i]);
G[i].clear();
}
for(i = 0; i < m; i++)
{
scanf("%d%d\n",&a,&b);
G[a].push_back(b);
}
now = sum = 0;
while(true)
{
to = 0;
mx = 0;
sz = G[now].size();
if(sz==0) break;
for(j = 0; j < sz; j++)
{
if(s[G[now][j]] > mx)
{
mx = s[G[now][j]];
to = G[now][j];
}
}
sum += mx;
now = to;
}
printf("Case %d: %d %d\n",k,sum,now);
}
return 0;
}