在一个地图上有n个地窖(n≤200),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径,并规定路径都是单向的,且保证都是小序号地窖指向大序号地窖,也不存在可以从一个地窖出发经过若干地窖后又回到原来地窖的路径。某人可以从任意一处开始挖地雷,然后沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使他能挖到最多的地雷。
输入格式:
第一行:地窖的个数;
第二行:为依次每个地窖地雷的个数;
下面若干行:
xi yi //表示从xi可到yi,xi<yi。
最后一行为"0 0"表示结束。
输出格式:
k1-k2−…−kv //挖地雷的顺序
挖到最多的雷。
输入样例:
6
5 10 20 5 4 5
1 2
1 4
2 4
3 4
4 5
4 6
5 6
0 0
输出样例:
3-4-5-6
34
代码及详细注释:
#include <iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int path[200]={0}; //每次dp方程转移时记录转移到该点的上一个点是谁(path[j]=i) 当然没挖到的点值始终为0
int a[200]; //a[i]为第i个点的地雷数
int d[200]; //d[i]到达i点能挖到的最多地雷数
for(int i=1;i<=n;i++)
{
cin>>a[i];
d[i]=a[i];
}
int v,u;
bool vis[200][200]; //vis[i][j] i能到达j
while(1)
{
cin>>v>>u;
if(v==0&&u==0) break;
vis[v][u]=true;
}
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
if(vis[i][j]&&d[j]<d[i]+a[j])
{
d[j]=d[i]+a[j];
path[j]=i; //记录路径(上一个点)
}
}
}
int max=0; //最多地雷数
int k; //找到最大的那个i 即最后一口井的序号
for(int i=1;i<=n;i++)
{
if(d[i]>max)
{
max=d[i];
k=i;
}
}
//但是并不能直接输出path数组!!而是要创建print
//附图解
int print[200];
print[0]=k;
int print_size=1; //因为print[0]已经存好了 哈哈
for(int i=1;;i++)
{
if(path[k]==0) break;
print[i]=path[k];
k=path[k];
print_size++;
}
for(int i=print_size-1;i>=0;i--)
{
if(i>0) cout<<print[i]<<"-";
else cout<<print[i];
}
cout<<endl;
cout<<max;
return 0;
}