题解 CF24A 【Ring road】
不是很懂楼上大佬的链式前向星,所以这里写一发常规的大法师
题意:
给我们一个图 :一共n个点,然后给出n条路,
每个路正向的边权是0,反向的边权是v
(正向的路已经建好,v是建反方向路的代价)
让我们找出一个边权最小且经过所有点的环
因为需要两两之间可达且费用最低
思路:
正常的DFS肯定是超时的,所以我们需要必要的剪枝,用记忆化搜索来找环,如果这个点被访问过了,我们不需要在搜索这个点
(因为环上面的点最多只出现一次)
CODE:
#include<bits/stdc++.h>
#define maxn 233
using namespace std;
int edge[maxn][maxn];
int vis[maxn];
int minn,n,e,v,s;
void dfs(int st,int en,int sum,int step)
{
if(st==en&&step==n)//如果起点终点一样,且一共经过了n个点那么更新最小值
{
minn=min(minn,sum);
}
for(int i=1;i<=n;i++)
{
if(vis[i]==1)//如果访问过就跳过
continue;
if(edge[en][i]!=0&&edge[i][en]==0)//如果i这个点没访问过且这条边存在且是边权不为零的边,那将en调整成i继续往下走
{
vis[i]=1;//记忆化搜索的步骤
dfs(st,i,sum+edge[en][i],step+1);
vis[i]=0;//记忆化搜索的步骤
}
else if(edge[en][i]==0&&edge[i][en]!=0)//如果i这个点没访问过且这条边存在且是边权为零的边,那将en调整成i继续往下走
{
vis[i]=1;
dfs(st,i,sum,step+1);
vis[i]=0;
}
}
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>s>>e>>v;
edge[s][e]=0;
edge[e][s]=v;
}
minn=100000000;
dfs(1,1,0,0);
cout<<minn<<endl;//输出经过所有点的最小环
return 0;
}