题目描述
在一个地图上有N个地窖(N<=200),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径,并规定路径都是单向的,也不存在可以从一个地窖出发经过若干地窖后又回到原来地窖的路径。某人可以从任一处开始挖地雷,然后沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使他能挖到最多的地雷。
输入
第一行输入一个整数N
第2行输入N个整数,表示每个地窖的地雷数
之后有若干行表示2个地窖之间有路径,输入 0 0代表结束
输出
第一行输出挖地雷的顺序,之间用-隔开
第2行输出最多挖出的地雷数
样例输入 Copy
6 5 10 20 5 4 5 1 2 1 4 2 4 3 4 4 5 4 6 5 6 0 0
样例输出 Copy
3-4-5-6 34
提示
编号大的地窖没有到编号小的地窖的路径
#include<iostream>
int a[1000];//这里存放的是不修改的地雷
int b[1000];//这里存放的是修改后能达到最大的地雷
int c[1000];//这里存放的是当前达到最大地雷数的前一个位置,方便动态规划
int f[200][200];//这里存放的是能否联通
using namespace std;
int main()
{
int n,x,y;
cin>> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
b[i] = a[i];
}
while (cin >> x >> y)
{
if (x == 0 && y == 0)
{
break;
}
f[x][y] = 1;
}
int sum = 0;
int t;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j < i; j++)
{
if (f[j][i] && b[i] < b[j] + a[i])
{
b[i] = b[j] + a[i];
c[i] = j;
}
}
if (b[i] > sum)
{
sum = b[i];
t= i;
}
}
//巧妙之处在于c[t]=-1这句话,他是让满足条件的此数输出,而不是去让c[t]得到的值再去等于-1
while (c[t])
{
int v = c[t];
c[t] = -1;
t= v;
}
//要好好理解这三行代码
cout << t;
for (int i = 1; i <= n; i++)
{
if (c[i] < 0)
{
cout << "-"<<i;
}
}
cout << endl<<sum << endl;
return 0;
}