1:思路分析:
:写图论题已经习惯先看一眼题解,基本可以筛选出或者排除一些算法
嗯....滑啊滑...n<=100.en....(cos:floyd吧,那又可以水过啦),看了一遍题意,确实floyd最短路+枚举路径顺序,拿捏!~
2:注意事项:
拿上我们全排列好bro,登登,闪亮登场:nenxt_permutaion(a+1,a+1+n);
注意!sort(a+1,a+1+n);//************使用next_permumation,前要先排序!!
//不然wa哭你,就因为这个我wa了好几发!
因为(why):nenxt_permutaion(a+1,a+1+n)是从当前形态开始算,下一个是当前形态的最小变化的更大排列!!!!
3:两个路径遍历方式(next_permutation vs dfs)dfs快一些
next_permutation:
sort(b+1,b+1+p);//************使用next_permumation,前要先排序!!
//不然wa哭你,就因为这个我wa了好几发!
b[0]=1,b[p+1]=n;//起点,终点
do{//暴力全排列所有路径可以
int sum=0;
for(int i=0;i<p+1;i++){
sum+=mp[b[i]][b[i+1]];
}
mmin=min(mmin,sum);
}while(next_permutation(b+1,b+1+p));//全排列,即暴力全最小值
dfs:
dfs(1,p,0);//暴力枚举 路径
void dfs(int now,int m,int sum){
if(m==0){
ans=min(ans,sum+mp[now][n]);
}
else{
for(int i=1;i<=p;i++){
if(!vis[i]){
vis[i]=true;
dfs(b[i],m-1,sum+mp[now][b[i]]);
vis[i]=false;
}
}
}
}
---------------------------------------------------------------------------------------------------------------------------------
4:okk上ACcode:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x3f3f3f3f
const int N=1e2+10;
int mp[N][N],b[15],n,p,x;
void floyd(){
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
}
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++){//建图
for(int j=1;j<=n;j++){
cin>>mp[i][j];
}
}
floyd();//Floyd
cin>>p;
int mmin=inf;
for(int i=1;i<=p;i++) cin>>b[i];
sort(b+1,b+1+p);//************使用next_permumation,前要先排序!!
//不然wa哭你,就因为这个我wa了好几发!
b[0]=1,b[p+1]=n;//起点,终点
do{//暴力全排列所有路径可以
int sum=0;
for(int i=0;i<p+1;i++){
sum+=mp[b[i]][b[i+1]];
}
mmin=min(mmin,sum);
}while(next_permutation(b+1,b+1+p));//全排列,即暴力全最小值
cout<<mmin<<"\n";
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int tt=1;
//cin>>tt;
while(tt--){
solve();
}
return 0;
}
2:路径遍历二之--dfs要比全排列快!
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x3f3f3f3f
const int N=1e2+10;
int mp[N][N],b[15],n,p,ans=0x7ffffff;
bool vis[15];
void dfs(int now,int m,int sum){
if(m==0){
ans=min(ans,sum+mp[now][n]);
}
else{
for(int i=1;i<=p;i++){
if(!vis[i]){
vis[i]=true;
dfs(b[i],m-1,sum+mp[now][b[i]]);
vis[i]=false;
}
}
}
}
void floyd(){
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
}
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++){//建图
for(int j=1;j<=n;j++){
cin>>mp[i][j];
}
}
cin>>p;
for(int i=1;i<=p;i++) cin>>b[i];
floyd();//Floyd
dfs(1,p,0);//暴力枚举 路径
cout<<ans<<"\n";
}
signed main(){
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int tt=1;
//cin>>tt;
while(tt--){
solve();
}
return 0;
}
over~