0
点赞
收藏
分享

微信扫一扫

L3-011 直捣黄龙(纯DFS)

软件共享软件 2022-04-22 阅读 36
算法c++dfs

因为迪杰斯特拉要考虑的关键字太多,并且还有一个关键字为路径长度,不好写。可以尝试以下搜索,当然这是因为这题的数据量并不大。
比较简单,详情看注释

#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
#include<queue>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int,ll> PII;
const int N=205;
const ll inf=1e18;

//cnt为最短路径的条数,题目保证存在这样的路径,所以cnt最小值为1 
int n,m,cnt=1;
//邻接表存图,g[i].first表示i到first存在一条值为g[i].second路径 
vector<PII> g[N];
//vis表示该点是否被访问过 
bool vis[N];
//存每个点的敌人数量 
ll v[N];
//将城市名映射为数字 
unordered_map<string,int> mp;
//将数字映射为城市名 
string name[N];
//城市名对应的编号 
int idx;
//起点和终点的城市名 
string st,ed;
//起点和终点对应的编号 
int id1,id2;
//path存储当前搜索的路径,res为最终路径 
vector<int> res,path;
//cnt1是路径长度,cnt2杀敌数量 
ll cnt1=inf,cnt2;
//在搜索过程中,储存对应cnt1,cnt2两个变量 
ll tmp1,tmp2;

void dfs(int u)
{
	if(u==id2)//达到终点 
	{
		if(tmp1<=cnt1)//路径的长度小于答案的长度 
		{
			//统计最短路径条数,若有比答案还小的则置为1(当前的路径为1) 
			if(tmp1==cnt1)
				++cnt;
			else
				cnt=1;
			//路径长度一样比较经过点的个数  
			if(tmp1==cnt1&&res.size()>path.size())
				return;
			//经过点的个数相同比较杀敌数量
			if(tmp1==cnt1&&res.size()==path.size()&&cnt2>tmp2) 
				return;
			//比答案更优,更新答案 
			cnt1=tmp1;
			cnt2=tmp2;
			res=path;
		}
		return ;
	}
	//搜索过程 
	for(int i=0;i<g[u].size();++i)
	{
		int to=g[u][i].first;
		if(vis[to])
			continue;
		vis[to]=1;
		tmp1+=g[u][i].second;
		tmp2+=v[to];
		path.push_back(to);
		dfs(to);
		vis[to]=0;
		tmp1-=g[u][i].second;
		tmp2-=v[to];
		path.pop_back();
	}
	return ;
}



int main()
{
	cin>>n>>m>>st>>ed;
	mp[st]=++idx;
	name[idx]=st;
	mp[ed]=++idx;
	name[idx]=ed;
	id1=mp[st];
	id2=mp[ed];
	for(int i=1;i<=n-1;++i)
	{
		string tmp;
		ll t;
		cin>>tmp>>t;
		//cout<<tmp<<'\n';
		if(mp.count(tmp)==0)
			mp[tmp]=++idx;
		v[mp[tmp]]=t;
		name[mp[tmp]]=tmp;
	}
	while(m--)
	{
		string x,y;
		cin>>x>>y;
		ll w;
		scanf("%lld",&w);
		g[mp[x]].push_back({mp[y],w});
		g[mp[y]].push_back({mp[x],w});
	}
	vis[id1]=1;
	dfs(id1);
	cout<<st<<"->";
	for(int i=0;i<res.size();++i)
	{
		cout<<name[res[i]];
		if(i!=res.size()-1)
			cout<<"->";
	}
	puts("");
	cout<<cnt<<" ";
	cout<<cnt1<<' '<<cnt2<<'\n';
	return 0;
}

/*
4 4 a c
b 10
c 10
d 0 
a b 1
b c 2
b d 1
d c 1
*/
举报

相关推荐

0 条评论