题目描述
输入
输出
输入样例
2
3
0 70 90
4
1 2
1 3
2 4
3 4
3
0 90 70
4
1 2
1 3
2 4
3 4
输出样例
CASE 1#
points : 90
circuit : 1->3->1
CASE 2#
points : 90
circuit : 1->2->1
思路:题目的意思是求最长路径.每个点都有一个趣味大小,我们要求的是最大的趣味大小,以及找到其路径(关键路径).
并且旅行路径只能从小往大走,那就说明对于某个点x,其前驱点一定小于该点.所以我们可以使用两个for循环对其进行松弛操作.
图中起始点和最后的终点是一样的,但由于只能往大点走,所以出发点的标号即是1又是N+1.
参考代码
#include<iostream>
#include<string.h>
using namespace std;
const int maxn = 110;
int map[maxn][maxn],qd[maxn],dis[maxn],p[maxn],T,n,m,u,v;//
void printPath(int s){//递归从前往后输出点.
if(s==-1){
return;
}
printPath(p[s]);
cout<<s<<"->";
}
int main()
{
cin>>T;
for(int k = 1; k <= T;k++){
//数据初始化
memset(map,0,sizeof(map));
memset(qd,0,sizeof(qd));
memset(dis,0,sizeof(dis));
memset(p,-1,sizeof(p));
cin>>n;
for(int i = 1;i <= n; i++){//对趣点进行初始化
cin>>qd[i];
}
qd[n+1] = 0;//最后一个趣点进行手动初始化
cin>>m;
for(int i = 1;i <= m;i++){//边进行初始化
cin>>u>>v;
map[u][v] = 1;
}
for(int i = 1;i <= n+1; i++){//对每个节点进行松弛
for(int j = 1;j < i; j++){
if(map[j][i]&&dis[j]+qd[i]>dis[i]){
dis[i] = dis[j]+qd[i];
p[i] = j;
}
}
}
cout<<"CASE "<<k<<"#"<<endl;
cout<<"points : "<<dis[n+1]<<endl;
cout<<"circuit :"<<" ";
printPath(p[n+1]);//从最后一个节点的前驱开始往前递归,依次输出节点.
cout<<1<<endl;
if(k!=T){
cout<<endl;
}
}
return 0;
}