求助,第 10 个点总是 TLE,不知道怎么优化了
我加了一些注释,便于理解
#include <cstdio>
using namespace std;
int n,m,k,s,t;
int c[101],last[101],ans=0x3f3f3f3f;
bool studied[101],pc[101][101];
struct line{//邻接链表存图
int u,v,w,pre;//u:起点,v:重点,w:权值(题目中是距离),pre:与这条边同一条起点的上一条边
}l[10001];
void dfs(int start,int dis)
{
if(start==t)//如果起点和终点相同,更新一下ans
{
if(dis<ans)ans=dis;
return;
}
if(dis>=ans)return;//剪枝优化
for(int i=last[start];i!=0;i=l[i].pre)//遍历起点的所有出边
{
int zd=l[i].v;//zd储存这条边的目的地
if(!studied[c[zd]]&&!pc[c[zd]][c[start]])
//如果国家zd的文化还没有学习并且zd的文化不排斥起点的文化
{
bool flag=true;
for(int j=1;j<=k;j++)//看看zd的文化和学习过的文化有没有排斥的
if(pc[c[zd]][j]&&studied[j])
{
flag=false;
break;
}
if(!flag)continue;//如果zd的文化和学习过的文化有排斥的,这条路不能走
studied[c[zd]]=true;//zd的文化标记为已学习
dfs(zd,dis+l[i].w);//起点设置为zd,走过的距离设置为当前距离+这条边的权值,继续深搜
studied[c[zd]]=false;//回溯
}
}
}
int main()
{
scanf("%d%d%d%d%d",&n,&k,&m,&s,&t);
for(int i=1;i<=n;i++)
scanf("%d",&c[i]);
for(int i=1;i<=k;i++)
for(int j=1;j<=k;j++)
scanf("%d",&pc[i][j]);
for(int i=1,x,y,w;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&w);
l[i*2-1].u=x;//由于题目中各个国家之间的道路是无向边,所以边要存放两条
l[i*2-1].v=y;//一条从x到y,一条从y到x
l[i*2-1].w=w;
l[i*2-1].pre=last[x];//last数组:以下标为起点的最后一条边
last[x]=i*2-1;
l[i*2].u=y;
l[i*2].v=x;
l[i*2].w=w;
l[i*2].pre=last[y];
last[y]=i*2;
}
if(c[s]==c[t])//起点和终点文化相同,输出-1
{
printf("-1\n");
return 0;
}
studied[c[s]]=true;//起点的文化标记为已学习
dfs(s,0);//求起点到终点的最短距离
if(ans==0x3f3f3f3f)printf("-1\n");
else printf("%d\n",ans);
return 0;
}