【例9.6】挖地雷
链接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1262
时间限制: 1000 ms 内存限制: 65536 KB
【题目描述】
在一个地图上有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
题解:f[i]表示第i个个坑作为起点最多可得挖多少, a[i]表示第i个地雷的下一点
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int h[205],f[205],mp[205][205],a[205]; int main() { int n,ans=0,k=0; cin>>n; memset(f,0,sizeof(f)); for(int i=1;i<=n;i++){ cin>>h[i]; f[i]=h[i]; } int x,y; while(cin>>x>>y) { if(!x&&!y)break; mp[x][y]=1; } a[n]=0; for(int i=n-1;i>0;i--) for(int j=i+1;j<=n;j++) if(mp[i][j]&&f[j]+h[i]>f[i]) { f[i]=f[j]+h[i]; a[i]=j; } for(int i=1;i<=n;i++) if(ans<f[i]){ ans=f[i];k=i; } cout<<k; k=a[k]; while(k){ cout<<"-"<<k; k=a[k]; } cout<<endl<<ans<<endl; }