甲级PAT1003 最短路+DFS

  1. 题目大意:给出一个图,并给出图的点权,寻找最短路的条数,所有最短路中点权和最大的值。
  2. 思路:参考晴神宝典的dij+DFS模板,虽然说硬背过也可以,但是还是建议理解后,能自己完全掌控算法的各个细节,并且完全靠自己整理思路写出来一遍才能算真正掌握。(跟数学题一样其实)
  3. 易错点:好久没有写最短路,导致跟屏幕谈心了好久。费劲心思写出来了还出现了好几次处错,由于ban了debug调试工具,就当练习cout输出调试了吧,(程序员の自我安慰) 主要错误有: 选出最小节点时应为未访问节点,判断是否更新时应该使用if else-if而不是两个if(这样会多录入一个相同的点)最后注意输出的时候不要有额外的空格
  4. 不认识的单词(本英语渣渣的专属板块):
    scattered 分散的
    call up as many hands on the way as possible.在路上召集尽可能多的人帮忙。
    *respectively 分别的
  5. 代码
//虽然函数名是BFS实际上是DFS写的时候憨憨化了
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=1010;
const int INF=0x3fffffff;
struct rode{
	int place,dis;
};
bool vis[maxn];
int d[maxn];
vector<int> pre[maxn];
vector<rode> G[maxn];
int N,M,st,en;
int team[maxn];
void dij(int s){
	fill(d,d+maxn,INF);
	fill(vis,vis+maxn,false);
	d[s]=0; //为起点
	for(int j=0;j<N;j++){
	int Min=INF,p;
		for(int i=0;i<N;i++){
			if(d[i]<Min&&vis[i]==false){
				Min=d[i];
				p=i;
			}
		}
		if(Min==INF) return ;
		vis[p]=true;
		for(int i=0;i<G[p].size();i++){
			if(G[p][i].dis+d[p]<d[G[p][i].place]&&vis[G[p][i].place]==false){
				d[G[p][i].place]=G[p][i].dis+d[p];
				pre[G[p][i].place].clear();
				pre[G[p][i].place].push_back(p);
			}
			else if(G[p][i].dis+d[p]==d[G[p][i].place]&&vis[G[p][i].place]==false){
				pre[G[p][i].place].push_back(p);
			}
		}
	}
	return ;
}
vector<int> path,temp;
int Max=0,tmax=0,ans=0;
void BFS(int now,int s){
	temp.push_back(now);
	if(now==s){
		ans++;
		for(int i=0;i<temp.size();i++){tmax+=team[temp[i]];}
		if(tmax>Max) {Max=tmax;path=temp;}
		tmax=0;
		return;
	}
	for(int i=0;i<pre[now].size();i++){
		BFS(pre[now][i],s);
		temp.pop_back();
	}
}


int main(){
	freopen("D:\\PAT\\in.txt","r",stdin);
	scanf("%d%d%d%d",&N,&M,&st,&en);
	for(int i=0;i<N;i++){
		scanf("%d",&team[i]);
	}
	for(int i=0;i<M;i++){
		int ta,tb,num;
		scanf("%d%d%d",&ta,&tb,&num);
		rode lambda;
		lambda.dis=num;
		lambda.place=tb;
		G[ta].push_back(lambda);
		lambda.place=ta;
		G[tb].push_back(lambda);
	}
	//for(int i=0;i<N;i++){for(int j=0;j<G[i].size();j++){cout<<G[i][j].place<<" "<<G[i][j].dis<<" ";}cout<<endl;}
	dij(st);
	//for(int i=0;i<N;i++){for(int j=0;j<pre[i].size();j++){cout<<pre[i][j]<<" ";}cout<<endl;} 
	BFS(en,st);
	cout<<ans<<" "<<Max;
	//for(int i=0;i<path.size();i++){cout<<path[i]<<endl;}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值