求助,离奇RE 10pts.
查看原帖
求助,离奇RE 10pts.
614725
masonpop楼主2022/11/21 22:21

写的爆搜。结果RE 10pts.看不出来哪里会RE,求调。

#include <bits/stdc++.h>
using namespace std;
const int inf=1917483645;
const int maxn=20;
int vis[maxn],len[maxn],deg[maxn];
//已访问的点,路径长度,出度数
int w[maxn][maxn],p[maxn][maxn];
int now;
//p[i][j]:点i第j条边能到的点(按边权排序后)
int n,m,ans=inf,tot,cnt,tmp;//tmp理论最优值,有点像A*了
inline bool cmp(int a,int b){return w[now][a]<w[now][b];}//排序
#define itn int
#define re return
inline void dfs(int num,int cur)//当前开发到哪个店,剪枝参数
{
	for(int i=num;i<=cnt;i++)//枚举通过那个已访问的点转移
	{
		if(tot+tmp*len[vis[i]]>ans)return;//剪枝:最优性 
        for(int j=cur;j<=deg[vis[i]];j++)//扩展到哪 
        {
        	if(!len[p[vis[i]][j]]) //没有被访问 
			{ 
	            ++cnt; 
	            vis[cnt]=p[vis[i]][j];//新建节点 
	            tmp-=w[vis[tot]][p[vis[tot]][1]];
	            tot+=w[vis[i]][vis[cnt]]*len[vis[i]];//累加 
	            len[vis[cnt]]=len[vis[i]]+1; 
	            dfs(i,j+1);
	            tot-=w[vis[i]][vis[cnt]]*len[vis[i]];
	            len[vis[cnt]]=0;
	            tmp+=w[vis[cnt]][p[vis[cnt]][1]];
	            cnt--;//回溯 
	        }
		}
		cur=1;//改回来 
	} 
	if(cnt==n)//终点 
	{
		if(tot<ans)ans=tot;
		return;
	}
} 
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)w[i][j]=inf;
	}
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
        scanf("%d%d%d",&x,&y,&z); 
        if(w[x][y]>=z)
        {
        	if(w[x][y]==inf)
        	{
        		p[x][++deg[x]]=y, p[y][++deg[y]]=x;
			}
        	w[x][y]=w[y][x]=z;
		}  
    }
	for(int i=1;i<=n;i++)
	{
		now=i;
		sort(p[i]+1,p[i]+deg[i]+1,cmp);//排序
		tmp+=w[i][p[i][1]];//开始全部加上 
	}
	for(int i=1;i<=n;i++)
	{
		tot=0;cnt=1;
		vis[1]=i;//第一个
		tmp-=w[i][p[i][1]];//减掉
		len[i]=1;
		dfs(1,1);
		len[i]=0;
		tmp+=w[i][p[i][1]];
		vis[1]=0; 
	}
	printf("%d\n",ans);
	return 0;
 } 
2022/11/21 22:21
加载中...