QAQ
DFS 爆搜+剪枝
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
bool vis[10001];
bool ok[10001][10001];
int dis[10001],w[1001];
int head[200000],net[200000],to[200000],cost[200000],cnt;
int n,k,s,t,m;
int ans=1e8;
queue <int> dl;
int wx[999],cntx;
void add(int x,int y,int z)
{
cnt++;
cost[cnt]=z;
to[cnt]=y;
net[cnt]=head[x];
head[x]=cnt;
}
bool check(int q)
{
int xx=w[q];
//if(vis[xx]) return 0;
for(int i=1;i<=cntx;i++)
if(ok[xx][wx[i]]) return 0;
return 1;
}
void dfs(int x,int Dis)
{
//printf("%d\n",x);
if(x==s)
{
ans=min(Dis,ans);
return;
}
for(int i=head[x];i;i=net[i])
{
int p=to[i];
if(dis[x]+cost[i]>=dis[p]||vis[w[p]]) continue;
dis[p]=dis[x]+cost[i];
if(check(p)) vis[w[p]]=1,wx[++cntx]=w[p],dfs(p,Dis+cost[i]),vis[w[p]]=0,cntx--;
}
}
int main()
{
memset(dis,127/3,sizeof(dis));
scanf("%d%d%d%d%d",&n,&k,&m,&t,&s);
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
for(int i=1;i<=k;i++)
for(int j=1;j<=k;j++)
scanf("%d",&ok[i][j]);
for(int i=1;i<=m;i++)
{
int u,v,d;
scanf("%d%d%d",&u,&v,&d);
add(u,v,d),add(v,u,d);
}
memset(vis,0,sizeof(vis));
dis[t]=0;
wx[1]=w[t];cntx=1;
vis[w[t]]=1;
dfs(t,0);
//printf("%d",dis[t]);
if(ans==1e8) ans=-1;
//vis[1]=1;
printf("%d",ans);
return 0;
}