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。(注意:要把路径先排序)
*/
// 标程:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int a[210],b[210]; struct ss { int x,y; }dp[50000]; ss dp1[210]; bool cmp(ss c1,ss c2) { if(c1.x!=c2.x) return c1.x<c2.x; else if(c1.y!=c2.y) return c1.y<c2.y; } int main() { //freopen("b.txt","r",stdin); int n,m,i,x,y,t; scanf("%d",&t); while(t--) { memset(b,0,sizeof(b)); memset(dp1,0,sizeof(dp1)); scanf("%d",&n); int max1=0,flag=0; for(i=1;i<=n;i++) { scanf("%d",&a[i]); dp1[i].x=a[i]; if(a[i]>max1) { max1=a[i]; flag=i;} } int max=0,ans=0,k=0,j=0; while(scanf("%d%d",&x,&y)) { if(!x && !y) break; dp[j].x=x, dp[j].y=y; j++; } sort(dp,dp+j,cmp); for(i=0;i<j;i++) { if(dp1[dp[i].y].x<dp1[dp[i].x].x+a[dp[i].y]) { dp1[dp[i].y].x=dp1[dp[i].x].x+a[dp[i].y]; dp1[dp[i].y].y=dp[i].x; } if(dp1[dp[i].y].x>max) { max=dp1[dp[i].y].x, ans=dp[i].y; } } b[0]=ans; k=1; while(1) { ans=dp1[ans].y; if(ans==0) break; b[k++]=ans; } if(k>1) { for(i=k-1;i>0;i--) printf("%d-",b[i]); printf("%d\n",b[0]); printf("%d\n",max); } if(k==1) printf("%d\n%d\n",flag,max1); } return 0; }