题目:朋也与光玉
思路:
状压dp。
f[i][j]当前获得光玉的状态为i,最后走到了j的最短路径。
代码:
#include<bits/stdc++.h>
using namespace std;
#define maxn 100
#define maxm 10000
#define maxk 13
#define read(x) scanf("%d",&x)
struct Edge{
int y,z;
Edge(){}
Edge(int yy,int zz) {
y=yy,z=zz;
}
};
int n,m,k;
int a[maxn+5];
vector<Edge> g[maxn+5];
int f[1<<maxk][maxn+5];
void readin() {
read(n),read(m),read(k);
for(int i=1;i<=n;i++) read(a[i]);
for(int i=1;i<=m;i++) {
int x,y,z;
read(x),read(y),read(z);
g[x].push_back(Edge(y,z));
}
}
int main() {
readin();
int s=(1<<k);
for(int i=1;i<s;i++) {
for(int j=1;j<=n;j++){
f[i][j]=1e9;
if(i==(1<<a[j])) f[i][j]=0;
}
}
for(int i=0;i<s;i++) {
for(int j=1;j<=n;j++){
if(i&(1<<a[j])) {
for(int u=0;u<g[j].size();u++) {
int x=g[j][u].y,y=g[j][u].z;
if(i&(1<<a[x])) continue;
f[i|(1<<a[x])][x]=min(f[i|1<<a[x]][x],f[i][j]+y);
}
}
}
}
int ans=1e9;
for(int i=1;i<=n;i++) {
ans=min(ans,f[s-1][i]);
}
if(ans!=1e9) printf("%d",ans);
else printf("Ushio!");
return 0;
}