hdu-6166(最短路+二进制分组)
题意:给你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(最短路+二进制分组)的更多相关文章
- HDU 6166 Senior Pan(二进制分组+最短路)
题意 给出一个\(n\)个点\(m\)条边的有向图\((n,m<=100000)\),从中选择\(k\)个点\((k<=n)\),问这k个点两两之间的最短路最小值是多少? 思路 直接的想法 ...
- HDU 6166 Senior Pan 二进制分组 + 迪杰斯特拉算法
Senior Pan Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Probl ...
- HDU - 6166:Senior Pan(顶点集合最短路&二进制分组)
Senior Pan fails in his discrete math exam again. So he asks Master ZKC to give him graph theory pro ...
- [bzoj4398] 福慧双修 最短路 二进制分组
---题面--- 题解: 考场上看的这道题,,,当时70分算法打挂了,今天才知道这个也是原题.... 首先,对于不跟1相邻的边,肯定不会经过两次,因为经过两次就回来了,除了增加路径长度之外没有任何意义 ...
- bzoj#2407-探险【最短路,二进制分组】
正题 题目链接:https://darkbzoj.tk/problem/2407 题目大意 \(n\)个点的一张无向图(但是正反权值不同),求一个从\(1\)出发回到\(1\)且不经过重复边的最短路径 ...
- hdu 6166 Senior Pan
http://acm.hdu.edu.cn/showproblem.php?pid=6166 题意: 给出一张无向图,给定k个特殊点 求这k个特殊点两两之间的最短路 二进制分组 枚举一位二进制位 这一 ...
- HDU 6166 Senior Pan(多校第九场 二进制分组最短路)
题意:给出n个点和m条有向边(有向边!!!!我还以为是无向查了半天),然后给出K个点,问这k个点中最近的两点的距离 思路:比赛时以为有询问,就直接丢了,然后这题感觉思路很棒,加入把所有点分成起点和终点 ...
- bzoj 4398 福慧双修——二进制分组
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 如果枚举1号点走哪些点出去,就从那些点出发跑多源最短路即可.最短路不会重复经过一条边. ...
- 题解 bzoj 4398福慧双修(二进制分组)
二进制分组,算个小技巧 bzoj 4398福慧双修 给一张图,同一条边不同方向权值不同,一条边只能走一次,求从1号点出发再回到1号点的最短路 一开始没注意一条边只能走一次这个限制,打了个从一号点相邻节 ...
随机推荐
- redis学习(四)——Hash数据类型
一.概述 我们可以将Redis中的Hash类型看成具有String Key和String Value的map容器.所以该类型非常适合于存储值对象的信息.如Username.Password和Age等. ...
- Generative Adversarial Nets[Vanilla]
引言中已经较为详细的介绍了GAN的理论基础和模型本身的原理.这里主要是研读Goodfellow的第一篇GAN论文. 0. 对抗网络 如引言中所述,对抗网络其实就是一个零和游戏中的2人最小最大游戏,主要 ...
- KNN-笔记(2)
1 - kd Tree KD树是一种对K维空间中的实例点进行存储以便对其进行快速检索的树形数据结构.KD树其实就是二叉树,表现为对K维空间的一个划分,构造kd树相当于不断的用垂直于坐标轴的超平面将k维 ...
- Shell第二篇:正则表达式和文本处理工具
一 什么是正则 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. 生活中处处都是正则: 比如我们描述:4条腿 ...
- Java过滤掉字符串中的html标签、style标签、script标签
使用正则表达式 import java.util.regex.Matcher; import java.util.regex.Pattern; public class HTMLSpirit{ pub ...
- 2018湘潭邀请赛C题(主席树+二分)
题目地址:https://www.icpc.camp/contests/6CP5W4knRaIRgU 比赛的时候知道这题是用主席树+二分,可是当时没有学主席树,就连有模板都不敢套,因为代码实在是太长了 ...
- 福大软工1816 · 课程计划预报(K班)
实践课安排 对应教学周序 时间 内容 3 09.22 业界交流讲座 6 10.13 团队选题报告答辩 7 10.20 UML设计 8 10.27 团队项目需求答辩 11 11.17 团队现场编程实战与 ...
- UITableView套UITableView数据刷新
https://www.jianshu.com/p/ee4b2bd54d08 网上关于tableview嵌套tableview的文章很多,纵览很多后发现有两点没有满足需求 把两个tableview放在 ...
- DevOps工程师到底做些什么?
我们之前已经听到很多谈论DevOps和DevOps世界的最新趋势的事情,但是就DevOps工程师本身,到底干些什么呢? 在最纯粹的存在形式上来说,DevOps工程师是为了加快开发和运营团队之间的交付效 ...
- p68理想的性质
1.如何由2.2.4推出后面的结论? 2.为什么A可以等于R? 3.如何证明3? π:R->R/M套用定理2.2.4(2)和(1) R2是R/M,I是R/M的理想也就是R2的理想,所以f^(-1 ...