数据最多14个有宝藏的地方,所以可以想到用状压dp
可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j]
本来想用Floyd写,无奈太弱调不出来。。后来改用spfa
然后进行dp,这基本是货郎担问题(TSP),状压中挺常出现的问题
f[s][i]表示状态s下到第i个有宝藏的地方,是否能拿到所有s中的宝藏
当然最后还要考虑dis[id[i]][1]是否大于s状态下的宝藏数,取较小值就是答案了
跑了48ms,优化一下应该可以更快。。
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> #define INF 0x3f3f3f3f using namespace std; ],dis[][],num,N,f[<<][],ans,vis[],mp[][]; void get_dis(int num){ queue<,sizeof(vis)); Q.push(num); dis[num][num]=INF; vis[num]=; while (!Q.empty()){ int now=Q.front(); Q.pop(); ; i<=n; i++){ ){ dis[num][i]=max(dis[num][i],min(dis[num][now],mp[now][i])); ; } } } } int main(){ scanf("%d%d%d", &n, &m, &K); ; i<=K; i++) scanf("%d", &id[i]); memset(dis,,sizeof(dis)); ,u,v,w; i<=m; i++) scanf("%d%d%d", &u, &v, &w),mp[v][u]=mp[u][v]=w; ; i<=n; i++) get_dis(i); N=(<<K); ; i<=K; i++) f[<<(i-)][i]=; ; s<N; s++){ num=; ; i<=K; i++) <<(i-))) num++; ; i<=K; i++) <<(i-))){ ; j<=K; j++) <<(j-)))) <<(j-))][j]|=f[s][i]; } ; i<=K; i++) <<(i-))) && f[s][i]){ ]); ans=max(ans,t); } } printf("%d\n", ans); ; }