题意:给你n个点m条边的有向图,然后再给你k个不同的点,问你这k个点的最小距离;

解题思路:这道题最需要注意的就是k个点一定是不同的,那么有一个结论就是任意两个不同的数字中,在他们的二进制地表示中,一定有一位是不同的,这样,我们就可以按照这个规律,把这些数字分成两组,按他们的二进制在某一位是0或者1分组,然后对每一位都跑一次最短路,这里的数据的二进制不超过20位

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 100500
#define inf 0x3f3f3f3f
using namespace std;
struct node
{
int num;
int dist;
node(int _num=0,int _dist=0):num(_num),dist(_dist){}
friend bool operator<(node a,node b)
{
return a.dist>b.dist;
}
};
struct Edge
{
int next;
int to;
int fa;
int w;
}edge[maxn];
int head[maxn];
int dist[maxn];
int cnt;
int visit[maxn];
int flag[maxn];
int n,m;
int k,x,y,w,t;
int pow(int u)
{
int x=1;
for(int i=1;i<=u;i++)
x=x*2;
return x;
}
void add(int u,int v,int w)
{
edge[cnt].next=head[u];edge[cnt].w=w;
edge[cnt].to=v;edge[cnt].fa=u;head[u]=cnt++;
}
void dij()
{
memset(dist,inf,sizeof(dist));
priority_queue<node>q;
for(int i=1;i<=n;i++)
{
if(flag[i]==1)
{
q.push(node(i,0));dist[i]=0;
}
}
while(!q.empty())
{
node now=q.top();q.pop();
x=now.num;
for(int i=head[x];i!=-1;i=edge[i].next)
{
int v=edge[i].to;
if(dist[v]>dist[x]+edge[i].w)
{
dist[v]=edge[i].w+dist[x];
q.push(node(v,dist[v]));
}
}
}
}
int main()
{
int tt;
int temp;
int cot=0;
scanf("%d",&tt);
while(tt--)
{
cot++;
//memset(flag,0,sizeof(flag));
memset(visit,0,sizeof(visit));
memset(head,-1,sizeof(head));
cnt=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&w);
add(x,y,w);
}
scanf("%d",&k);
for(int i=1;i<=k;i++)
{
scanf("%d",&t);
visit[t]=1;
}
int ans=inf;
for(int i=0;i<20;i++)
{
for(int j=1;j<=n;j++)
{
if(!visit[j])
continue;
temp=pow(i);flag[j]=0;
if((j&temp)==0)
{
flag[j]=1;
}
else
flag[j]=-1;
}
dij();
for(int j=1;j<=n;j++)
{
if(!visit[j])
continue;
if(flag[j]==-1)
ans=min(ans,dist[j]);
}
for(int j=1;j<=n;j++)
{
if(!visit[j])
continue;
temp=pow(i);flag[j]=0;
if((j&temp)==0)
{
flag[j]=-1;
}
else
flag[j]=1;
}
dij();
for(int j=1;j<=n;j++)
{
if(!visit[j])
continue;
if(flag[j]==-1)
ans=min(ans,dist[j]);
}
}
printf("Case #%d: %d\n",cot,ans);
}
}

  

,每一位分别跑两次最短路,一次是所有的0到所有的1,另一次是所有的1到所有的0,一共是四十次不到,如果根据每次给的n来跑,会更小。

ps:这里的最短路是多源多汇的;

代码:

hdu-6166(最短路+二进制分组)的更多相关文章

  1. HDU 6166 Senior Pan(二进制分组+最短路)

    题意 给出一个\(n\)个点\(m\)条边的有向图\((n,m<=100000)\),从中选择\(k\)个点\((k<=n)\),问这k个点两两之间的最短路最小值是多少? 思路 直接的想法 ...

  2. HDU 6166 Senior Pan 二进制分组 + 迪杰斯特拉算法

    Senior Pan Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Probl ...

  3. HDU - 6166:Senior Pan(顶点集合最短路&二进制分组)

    Senior Pan fails in his discrete math exam again. So he asks Master ZKC to give him graph theory pro ...

  4. [bzoj4398] 福慧双修 最短路 二进制分组

    ---题面--- 题解: 考场上看的这道题,,,当时70分算法打挂了,今天才知道这个也是原题.... 首先,对于不跟1相邻的边,肯定不会经过两次,因为经过两次就回来了,除了增加路径长度之外没有任何意义 ...

  5. bzoj#2407-探险【最短路,二进制分组】

    正题 题目链接:https://darkbzoj.tk/problem/2407 题目大意 \(n\)个点的一张无向图(但是正反权值不同),求一个从\(1\)出发回到\(1\)且不经过重复边的最短路径 ...

  6. hdu 6166 Senior Pan

    http://acm.hdu.edu.cn/showproblem.php?pid=6166 题意: 给出一张无向图,给定k个特殊点 求这k个特殊点两两之间的最短路 二进制分组 枚举一位二进制位 这一 ...

  7. HDU 6166 Senior Pan(多校第九场 二进制分组最短路)

    题意:给出n个点和m条有向边(有向边!!!!我还以为是无向查了半天),然后给出K个点,问这k个点中最近的两点的距离 思路:比赛时以为有询问,就直接丢了,然后这题感觉思路很棒,加入把所有点分成起点和终点 ...

  8. bzoj 4398 福慧双修——二进制分组

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 如果枚举1号点走哪些点出去,就从那些点出发跑多源最短路即可.最短路不会重复经过一条边. ...

  9. 题解 bzoj 4398福慧双修(二进制分组)

    二进制分组,算个小技巧 bzoj 4398福慧双修 给一张图,同一条边不同方向权值不同,一条边只能走一次,求从1号点出发再回到1号点的最短路 一开始没注意一条边只能走一次这个限制,打了个从一号点相邻节 ...

随机推荐

  1. 不可变对象和Biulder模式(面试问题)

    String就是一个典型的不可变对象.外界的操作不能改变它,如果尝试改变都会返回一个新的String对象. 具体实现起来就是把属性全部变成private 和 final的,这个类也是final的不可继 ...

  2. Linux内存管理之mmap详解

    转发之:http://blog.chinaunix.net/uid-26669729-id-3077015.html Linux内存管理之mmap详解 一. mmap系统调用 1. mmap系统调用  ...

  3. VS2015/Visual Studio快捷键无效问题

    0 VS2015快捷键无效问题的解决办法 快捷键的使用可以大大提高编码效率,VS为我们内置了不少的常用快捷键组合,实际使用过程中往往会随着计算机上安装其他软件引起快捷键冲突,导致VS快捷键失效,解决办 ...

  4. WebApi测试工具:SAEA.RESTED

    写好一个Api接口不知道怎么测试?试试SAEA.RESTED吧——无需任何代码.不污染主项目.快速上手.不依赖IIS,可供多人共享使用!下面就跟着本文查看如何使用吧:1.下载安装:https://gi ...

  5. c#简单的io

    读取路径判断文件是否存在,进行删除或者创建 简单的io using System; using System.Collections; using System.Collections.Generic ...

  6. Luogu P3321 [SDOI2015]序列统计

    一道不错的多项式好题.还涉及了一些数论内容. 首先我们看到题目是求乘积模\(m\)的方案数,考虑到这种方案数我们一般都可以用生成函数来做. 但显然卷积的下标有加(FFT,NTT等)有位运算(FWT)但 ...

  7. NCC Meetup 2018 Shanghai 活动小结(含PPT与视频)

    NCC Meetup 2018 上海的活动于2018年6月30日在微软上海港汇办公室进行.原本计划30人规模的小型活动,结果收到了逾60人的报名,其中大部均来到现场参加了活动. 本次活动得到了微软公司 ...

  8. 面试:用 Java 实现一个 Singleton 模式

    面试:用 Java 实现一个 Singleton 模式 面试系列更新后,终于迎来了我们的第一期,我们也将贴近<剑指 Offer>的题目给大家带来 Java 的讲解,个人还是非常推荐< ...

  9. 朱晔的互联网架构实践心得S1E2:屡试不爽的架构三马车

    朱晔的互联网架构实践心得S1E2:屡试不爽的架构三马车 [下载本文PDF进行阅读] 这里所说的三架马车是指微服务.消息队列和定时任务.如下图所示,这里是一个三驾马车共同驱动的一个立体的互联网项目的架构 ...

  10. Python_生成器函数进阶_39

    def generator(): print(123) content = yield 1 #content接收的是send传的值 print('=======',content) print(456 ...