问题描述
给定两张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;
}