挖地雷
Problem Description
在一个地图上有n个地窖(n<=200),每个地窖中埋有一定数量的地雷。
同时,给出地窖之间的连接路径,并规定路径都是单向的,也不存在可以从一个地窖出发经过若干地窖后又回到原来地窖的路径。
某人可以从任一处开始挖地雷,然后沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。
设计一个挖地雷的方案,使他能挖到最多的地雷。(用动态规划求解)
Input
输入有多组数据,
每组数据的第一行为一个整数n,表示地窖的个数,
第二行为n个地窖中的地雷数。下面多行数据以0,0结束,每行为两个数x和y,表示从x可以到y。
Output
对于每组数据输出两行,第一行为挖地雷的顺序,第二行为最多挖出的地雷数
Sample Input
1
6
5 10 20 5 4 5
1 2
1 4
2 4
3 4
4 5
4 6
5 6
0 0
Sample Output
3-4-5-6
34
dp方程:if(f[i][j]==1&&dp[i]<dp[j]+w[i])dp[i]=dp[j]+w[i];\\j>i
#include<stdio.h>
#include<string.h>
#define max(a,b) a>b?a:b
int w[205],dp[205],next[205],f[205][205];
int main(){
int m,a,b;
scanf("%d",&m);
while(m-->0){
memset(f,0,sizeof(f));
memset(dp,0,sizeof(dp));
int n,i,j;
scanf("%d",&n);
for(i=1;i<=n;i++){//输入各点地雷数
scanf("%d",&w[i]);
dp[i]=w[i];
next[i]=-1;
}
do{//输入地窖连通情况
scanf("%d%d",&a,&b);
if(a!=0&&b!=0){
f[a][b]=1;
}
}while(a!=0&&b!=0);
//核心算法
for(i=n;i>=1;i--){
for(j=i+1;j<=n;j++){
if(f[i][j]==1&&dp[i]<dp[j]+w[i]){
dp[i]=dp[j]+w[i];
next[i]=j;
}
}
}
//求可以获取最大地雷数
int ma_x=0,flag;
for(i=1;i<=n;i++){
if(ma_x<dp[i]){
ma_x=dp[i];
flag=i;
}
}
//输出结果
i=flag;
while(next[i]!=-1){
printf("%d-",i);
i=next[i];
}
printf("%d\n",i);
printf("%d\n",ma_x);
}
}