题目请点我
题解:
这是一道简单的深搜,找到最短的一个环。深搜遍历每一个点,注意剪枝,边为双向边,并且可能会有重边。
代码实现:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#define MAX_N 110
#define MAX_M 10010
#define INF 0x7fffffff
using namespace std;
int N,M;
int result;
int start;
int length;
bool flag;
//深搜时更新的数组
int lis[MAX_N];
//保存结果的数组
int save[MAX_N];
int visit[MAX_N];
int point[MAX_N][MAX_N];
//更新结果
void refresh(int len,int sum);
void dfs(int last,int pos,int len,int sum);
int main()
{
while( scanf("%d%d",&N,&M) != EOF ){
result = INF;
flag = false;
for( int i = 1; i <= N; i++ ){
for( int j = 1; j <= N; j++ ){
point[i][j] = INF;
}
lis[i] = 0;
save[i] = 0;
visit[i] = 0;
}
int x,y,l;
for( int i = 0; i < M; i++ ){
scanf("%d%d%d",&x,&y,&l);
//有重边,双向边
if( point[x][y] > l ){
point[x][y] = l;
point[y][x] = l;
}
}
for( int i = 1; i <= N; i++ ){
start = i;
lis[0] = i;
dfs(-1,i,0,0);
lis[0] = 0;
}
if( flag ){
for( int i = 0; i < length; i++ ){
printf("%d",save[i]);
if( i != length-1 ){
printf(" ");
}
else{
printf("\n");
}
}
}
else{
printf("No solution.\n");
}
}
return 0;
}
void dfs(int last, int pos,int len,int sum){
if( pos == start && len != 0 ){
if( result > sum ){
refresh(len,sum);
}
return ;
}
//剪枝
if( sum > result ){
return ;
}
for( int i = 1 ; i <= N; i++ ){
//相邻边&&未访问&&不是上一个节点
if( point[pos][i]!=INF && visit[i]==0 && i != last ){
lis[len+1] = i;
visit[i] = 1;
dfs(pos,i,len+1,sum+point[pos][i]);
lis[len+1] = 0;
visit[i] = 0;
}
}
return ;
}
void refresh(int len,int sum){
for( int i = 0; i < len; i++ ){
save[i] = lis[i];
}
flag = true;
result = sum;
length = len;
}