【动态规划1】动态规划的引入 P2196 挖地雷 深搜dfs
用邻接表存储图,减少遍历的复杂度,该题是有向图,第一次dfs是寻找最大值,第二次dfs是寻找最大值对应的路径。
AC代码如下:
#include <bits/stdc++.h>
using namespace std;
int head[25],tot,val[25],n,mx,f[25],flag;
struct node{
int to,next;
}e[25*25];
void add_edge(int u,int v){//邻接表
tot++,e[tot].to=v,e[tot].next=head[u],head[u]=tot;
}
void dfs(int fa,int x,int sum){//寻找最大值
int b,v;
if(mx<sum+val[x])mx=sum+val[x];
for(b=head[x];b;b=e[b].next){
v=e[b].to;
dfs(x,v,sum+val[x]);
}
}
void pos(int x){//打印挖雷路径
if(!x)return;
pos(f[x]);
printf("%d ",x);
}
void dfs2(int fa,int x,int sum){//寻找最大值对应的路径
int b,v;
f[x]=fa;
if(mx==sum+val[x]){
flag=1;
pos(x);
return;
}
for(b=head[x];b;b=e[b].next){
v=e[b].to;
dfs2(x,v,sum+val[x]);
}
}
int main(){
int i,j,k;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&val[i]);
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++){
scanf("%d",&k);
if(k)add_edge(i,j);//有向图
}
for(i=1;i<=n;i++)dfs(0,i,0);
for(i=1;i<=n;i++)
if(!flag)dfs2(0,i,0);
printf("\n%d\n",mx);
return 0;
}