Senior Pan

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1462    Accepted Submission(s): 573

Problem Description
Senior Pan fails in his discrete math exam again. So he asks Master ZKC to give him graph theory problems everyday.
The task is simple : ZKC will give Pan a directed graph every time, and selects some nodes from that graph, you can calculate the minimum distance of every pair of nodes chosen in these nodes and now ZKC only cares about the minimum among them. That is still too hard for poor Pan, so he asks you for help.
 
Input
The first line contains one integer T, represents the number of Test Cases.1≤T≤5.Then T Test Cases, for each Test Cases, the first line contains two integers n,m representing the number of nodes and the number of edges.1≤n,m≤100000
Then m lines follow. Each line contains three integers xi,yi representing an edge, and vi representing its length.1≤xi,yi≤n,1≤vi≤100000
Then one line contains one integer K, the number of nodes that Master Dong selects out.1≤K≤n
The following line contains K unique integers ai, the nodes that Master Dong selects out.1≤ai≤n,ai!=aj
 
Output
For every Test Case, output one integer: the answer
 
Sample Input
1
5 6
1 2 1
2 3 3
3 1 3
2 5 1
2 4 2
4 3 1
3
1 3 5
 
Sample Output
Case #1: 2
 
Source
    给出N个点和M条边的无向图,从中选出K个互不相同的点组成集合D,问从D中挑选任意两点间的最短路最小是多少。
如果让每个点都跑一次dij的话肯定会T。
       首先我们要知道对于求两个集合之间的最短路只要对每个集合建立一个超级点跑一次dij便可得到。可以想办法把这个集合划分成若两个个小集合然后减少dij运行次数,要满足所有的点对都会分在两个不同的集合中。利用二进制,两个点的编号都不相同,那么对于她们的二进制而言一定是有一位是不同的,点数最大为1e5,最多也就16位足以,这样每次根据第b位为0/1进行集合划分,最后就考虑了所有情况。第一发我让超级点建了双向边(为了省事)结果T了,后来每次都重新建边就3s过了。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<functional>
using namespace std;
#define LL long long
#define pii pair<int,int>
#define mp make_pair
#define inf 0x3f3f3f3f
int u[],v[],w[];
struct Edge{
int v,w,next;
Edge(){}
Edge(int v,int w,int next):v(v),w(w),next(next){}
}e[];
int first[],tot;
void add(int u,int v,int w){
e[tot]=Edge(v,w,first[u]);
first[u]=tot++;
}
bool vis[];
int d[];
int N,M,K;
void dij(int s){
memset(vis,,sizeof(vis));
memset(d,inf,sizeof(d));
d[s]=;
priority_queue<pii,vector<pii>,greater<pii> >q;
q.push(mp(,s));
while(!q.empty()){
int u=q.top().second;
q.pop();
if(vis[u]) continue;
vis[u]=;
for(int i=first[u];i+;i=e[i].next){
if(d[e[i].v]>d[u]+e[i].w){
d[e[i].v]=d[u]+e[i].w;
q.push(mp(d[e[i].v],e[i].v));
}
}
}
}
int main()
{
int t,i,a,j;
int cas=;
cin>>t;
while(t--){
vector<int>vi;
cin>>N>>M;
tot=;
for(i=;i<=M;++i){
scanf("%d%d%d",u+i,v+i,w+i);
}
scanf("%d",&K);
for(i=;i<=K;++i){
scanf("%d",&a);
vi.push_back(a);
}
printf("Case #%d: ",++cas);
int ans=inf;
for(int b=;b<;++b){
tot=;
memset(first,-,sizeof(first));
for(i=;i<=M;++i) add(u[i],v[i],w[i]);
for(i=;i<vi.size();++i){
if((vi[i]&(<<b))==){
add(,vi[i],);
}
else{
add(vi[i],N+,);
}
}
dij();
ans=min(ans,d[N+]); tot=;
memset(first,-,sizeof(first));
for(i=;i<=M;++i) add(u[i],v[i],w[i]);
for(i=;i<vi.size();++i){
if((vi[i]&(<<b))==){
add(vi[i],,);
}
else{
add(N+,vi[i],);
}
} dij(N+);
ans=min(ans,d[]);
}
cout<<ans<<endl;
}
return ;
}

HDU6166-求集合间的最短路的更多相关文章

  1. 零基础学习java------day14-----泛型,foreach,可变参数,数组和集合间的转换,Set,Map,

    1.泛型(jdk1.5以后出现) https://www.cnblogs.com/lwbqqyumidi/p/3837629.html#!comments (1)为什么要用泛型? 限制集合,让它只能存 ...

  2. DFS算法-求集合的所有子集

    目录 1. 题目来源 2. 普通方法 1. 思路 2. 代码 3. 运行结果 3. DFS算法 1. 概念 2. 解题思路 3. 代码 4. 运行结果 4. 对比 1. 题目来源 牛客网,集合的所有子 ...

  3. boost dijkstra获得两点间的最短路

    需求是只需要得到两点间的最短路,不需要求得单源对于全图的最短路,使用boost中的dijsktra_shortest_path,当得到目标点的最短路时直接throw exception. #inclu ...

  4. 求集合中选一个数与当前值进行位运算的max

    求集合中选一个数与当前值进行位运算的max 这是一个听来的神仙东西. 先确定一下值域把,大概\(2^{16}\),再大点也可以,但是这里就只是写写,所以无所谓啦. 我们先看看如果暴力求怎么做,位运算需 ...

  5. hdu 1856 求集合里元素的个数 输出最大的个数是多少

    求集合里元素的个数 输出最大的个数是多少 Sample Input41 23 45 61 641 23 45 67 8 Sample Output42 # include <iostream&g ...

  6. SQL_求集合中每天最大时间记录的总和

    --问题求 集合中每天最大时间的总和 表中的数据 列: 用户 分数 时间 A 2 2014-01-01 01:00:00 A 2 2014-01-01 02:00:00 A 2 2014-01-01 ...

  7. [C++]boost dijkstra获得两点间的最短路

    需求是只需要得到两点间的最短路,不需要求得单源对于全图的最短路,使用boost中的dijsktra_shortest_path,当得到目标点的最短路时直接throw exception. #inclu ...

  8. [CF1051F]The Shortest Statement (LCA+最短路)(给定一张n个点m条有权边的无向联通图,q次询问两点间的最短路)

    题目:给定一张n个点m条有权边的无向联通图,q次询问两点间的最短路 n≤100000,m≤100000,m-n≤20. 首先看到m-n≤20这条限制,我们可以想到是围绕这个20来做这道题. 即如果我们 ...

  9. AOJ -0189 Convenient Location && poj 2139 Six Degrees of Cowvin Bacon (floyed求任意两点间的最短路)

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=78207 看懂题就好. 求某一办公室到其他办公室的最短距离. 多组输入,n表示 ...

随机推荐

  1. python 之操作redis数据库(非关系型数据库,k-v)

    数据库: 1. 关系型数据库 表结构 2. 非关系型数据库 nosql (k - v 速度快),常用的时以下三种: memcache 存在内存里 redis 存在内存里 mangodb 数据还是存在磁 ...

  2. 51Nod 1079

    题目大意: 一个正整数K,给出K Mod一些质数的结果,求符合条件的最小的K.例如,K%2=1,K%3=2,K%5=3符合条件的最小的K=23. Input 第1行:1个数N表示后面输入的质数及模的数 ...

  3. 《mysql必知必会》读书笔记--触发器及管理事务处理

    触发器 触发器是MySQL响应DELETE,INSERT,UPDATE而自动执行的一条MySQL语句,其他语句不支持触发器. 创建触发器时,需要4个条件: 唯一的触发器名 触发器关联的表 触发器应该响 ...

  4. java 将小数拆分为两部分+浮点型精度丢失问题

    问题:将一个String类型的小数拆分为整数部分和小数部分,如9.9拆分为9和0.9 1.将小数的整数和小数部分拆分开 public float numberSub(String totalMoney ...

  5. hdu5716

    地址: 题目: 带可选字符的多字符串匹配 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Oth ...

  6. python 利用正则构建一个计算器

    该计算器主要分为四个模块: weclome_func函数用来进入界面获取表达式,并判断表达式是否正确,然后返回表达式: add_sub函数用来进行加减运算,如果有多个加减运算,会递归,最后返回对应的值 ...

  7. 【分库分表】sharding-jdbc—解决的问题

    一.遇到的问题 随着互联网技术和业务规模的发展,单个db的表里数据越来越多,sql的优化已经作用不明显或解决不了问题了,这时系统的瓶颈就是单个db了(或单table数据太大).这时候就涉及到分库分表的 ...

  8. Python面试题之回调函数

    0x00 概述 编程分为两类:系统编程(system programming)和应用编程(application programming).所谓系统编程,简单来说,就是编写库:而应用编程就是利用写好的 ...

  9. Thinkphp5.0实战开发一------命名空间详解

    序言 ThinkPHP是一个快速.兼容而且简单的轻量级国产PHP开发框架,使用ThinkPHP框架可以极大简化我们的开发过程,节省时间.这个专题我将记录自己学习使用ThinkPHP5.0的进行实战开发 ...

  10. s3cmd安装

    配置yum.repos cd /etc/yum.repos.d/ vim s3tools.repo [s3tools] name=Tools for managing Amazon S3 - Simp ...