题目大意

有 \(n(1 \leq n \leq 10000)\) 个城镇,由 \(1 \leq m \leq 50000\) 条无向道路连接。给出 \(k(1 \leq k \leq 5) 个超市\),现于剩下 \(n-k\) 个城镇中选择一个,使它到所有有超市的城镇再回来总路程最短

分析

注意到 \(k\) 很小,那我们就可以枚举经过这些超市的顺序,然后依次走最短路,再枚举一个另外出发城镇,由最后一个超市返回

于是就完了

\(Code\)

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std; const int N = 10005 , M = 50005;
int n , m , k , tot , cnt;
int a[N] , used[10] , b[10] , order[200][10] , vis[N] , dis[10][N] , h[N]; struct edge{
int to , nxt , w;
}e[M << 1];
struct node{
int id , d;
bool operator < (node c) const {return d > c.d;}
};
priority_queue<node> q; void add(int u , int v , int w){e[++tot] = edge{v , h[u] , w} , h[u] = tot;}
void dij(int s)
{
memset(vis , 0 , sizeof(vis));
for(register int i = 1; i <= n; i++) dis[s][i] = 1e8;
dis[s][a[s]] = 0;
while (!q.empty()) q.pop();
q.push((node){a[s] , 0});
while (!q.empty())
{
node x = q.top();
q.pop();
if (vis[x.id]) continue;
vis[x.id] = 1;
for(register int i = h[x.id]; i; i = e[i].nxt)
if (dis[s][x.id] + e[i].w < dis[s][e[i].to])
{
dis[s][e[i].to] = dis[s][x.id] + e[i].w;
q.push((node){e[i].to , dis[s][e[i].to]});
}
}
} void dfs(int x)
{
if (x > k)
{
++cnt;
for(register int i = 1; i <= k; i++) order[cnt][i] = b[i];
return;
}
for(register int i = 1; i <= k; i++)
if (!used[i])
{
used[i] = 1 , b[x] = i , dfs(x + 1);
used[i] = 0 , b[x] = 0;
}
} void solve()
{
int ans = 2e9;
dfs(1);
for(register int i = 1; i <= k; i++) dij(i);
memset(vis , 0 , sizeof vis);
for(register int i = 1; i <= k; i++) vis[a[i]] = 1;
for(register int i = 1; i <= cnt; i++)
{
int sum = 0;
for(register int j = 2; j <= k; j++) sum = sum + dis[order[i][j - 1]][a[order[i][j]]];
if (sum > ans) continue;
int Mi = 1e8;
for(register int j = 1; j <= n; j++)
if (!vis[j]) Mi = min(Mi , sum + dis[order[i][1]][j] + dis[order[i][k]][j]);
ans = min(ans , Mi);
}
printf("%d" , ans);
} int main()
{
scanf("%d%d%d" , &n , &m , &k);
for(register int i = 1; i <= k; i++) scanf("%d" , &a[i]);
int u , v , w;
for(register int i = 1; i <= m; i++)
scanf("%d%d%d" , &u , &v , &w) , add(u , v , w) , add(v , u , w);
solve();
}

最新文章

  1. 解决“Dynamic Web Module 3.0 requires Java 1.6 or newer.”错误
  2. Java中private、protected、public和default的区别
  3. LINQ函数
  4. 【Java心得总结二】浅谈Java中的异常
  5. IIS发布项目 遇到的error
  6. [原]常用sqlserver数据库使用sql语句
  7. ubuntu手贱改了sudoers权限之后的恢复
  8. 14.约瑟夫环问题[JosephusProblem]
  9. OUYA设备的购买和安装
  10. 程序设计: 猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。(C#语言)
  11. python测试基于websocket协议的即时通讯接口
  12. Vue.jsbrowserify项目模板
  13. Vue2反向代理
  14. Oracle DB 总结(SQL)
  15. python装饰器同时支持有参数和无参数的练习题
  16. javascript中加号(+)操作符的作用
  17. MT【259】2016天津压轴题之最佳逼近
  18. SpringMvc的Url映射和传参案例(转)
  19. C#中将String类型保存到本地文件的方法
  20. 批处理/命令行合并js,递归合并子目录js文件

热门文章

  1. jquery &amp;&amp;、||
  2. 踩坑记录:Redis的lettuce连接池不生效
  3. Python中open()文件操作/OS目录操作
  4. MAUI新生4.6-主题设置LightTheme&amp;DarkTheme
  5. Vue3 企业级优雅实战 - 组件库框架 - 9 实现组件库 cli - 上
  6. Python 文件操作(IO 技术)
  7. Java基于内存的消息队列实现
  8. MQ系列10:如何保证消息幂等性消费
  9. 【Python】pip的镜像安装异常解决方案
  10. C#开发的资源文件程序(可国际化) - 开源研究系列文章