0
点赞
收藏
分享

微信扫一扫

试题 算法提高 遍历

西特张 2022-03-30 阅读 36
c++算法

问题描述
  给定两张N个点的图,要求找出图中经过指定M个点的一条路径,希望路径最短。

输入格式
  第一行两个整数N,M。
  之后n行每行n个整数,其中第i行的第j个整数x表示i到j的路的长度(i,j从0到n-1)。0表示两点之间没有路。
  之后一行M个整数,表示指定的点的编号,编号从0开始。
输出格式
  一行一个整数表示路径长度。无解输出-1。 
样例输入
3 2
0 1 2
3 0 4
5 6 0
0 1

样例输出
1

数据规模和约定
  N <= 100 M <= 15

dp不会写只能dfs骗骗分了
骗了70分

#include<bits/stdc++.h>
using namespace std;
const int N = 1e2+5;
int r[N][N];
int s[N],z[N];
bool st[N];
set<int>v;
int n,m,an = 0x3f3f3f3f;
void dfs(int step,int u)
{
	if(u >= an) return;
	if(step >= m)
	{
		an = u;
		return;
	}
	for(int i = 0; i < m; i++)
	{
		if(st[i]) continue;
		st[i] = 1;
		s[step] = z[i];
		if(step >= 1)
		{
		int uu = u + r[s[step-1]][s[step]]; 
		dfs(step + 1,uu);
		}
		else dfs(step + 1, 0);
		st[i] = 0;
	}
}
int main()
{
	
	cin>>n>>m;
	for(int i = 0; i < n; i++)
	for(int j = 0; j < n; j++)
	{
		int a;
		cin>>a;
		if(a == 0) r[i][j] = 0x3f3f3f3f;
		else r[i][j] = a;
	}
	for(int i = 0; i < m; i++)
	{
		int a;
		cin>>a;
		v.insert(a);		
	}
	m = v.size();
	int o = 0;
	set<int>::iterator iter;
	for(iter = v.begin(); iter != v.end(); iter++)
	{
		z[o++] = *iter;
	}
	for(int k = 0; k < n; k++)
	{
		for(int i = 0; i < n; i++)
		{
			for(int j = 0; j < n; j++)
			{
				r[i][j] = min(r[i][j],r[i][k]+r[k][j]);
			}
		}
	}
	dfs(0,0);
	cout<<an<<endl;
    return 0;	
} 

骗了70分

举报

相关推荐

0 条评论