2017多校第9场 HDU 6166 Senior Pan 堆优化Dij

Posted Lsxxxxxxxxxxxxx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017多校第9场 HDU 6166 Senior Pan 堆优化Dij相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6166

题意:给你一个有向图,然后给你k个点,求其中一个点到另一个点的距离的最小值。

解法:枚举二进制位按照标号当前位为1 和当前位为0分为两个集合,每次求解两个集合之间的最短路即可覆盖到所有的点对。时间复杂度20*dijstla时间,这样做的正确性在哪?显然我们需要的答案至少有一个二进制位不同,那么这样求解肯定可以找到正确答案,事实上还可以随机分组emmmm。。。

 

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 100010;
const LL inf = 0x3f3f3f3f3f3f3f3f;
struct edge{
    int to,val,next;
}E[maxn];
int head[maxn],edgecnt,a[maxn];
bool vis[maxn];
LL dis[maxn];
void initedge(){
    edgecnt=0;
    memset(head,-1,sizeof(head));
}
void add(int u, int v, int w){
    E[edgecnt].to=v,E[edgecnt].val=w,E[edgecnt].next=head[u],head[u]=edgecnt++;
}
struct node{
    int x;
    LL step;
    node(int x, LL step):x(x),step(step){}
    bool operator < (const node &rhs) const{
        return step>rhs.step;
    }
};
priority_queue<node>q;
LL Dijstra(){
    while(!q.empty()){
        node now=q.top(); q.pop();
        if(vis[now.x]) return now.step;
        int u=now.x;
        for(int i=head[u]; ~i; i=E[i].next){
            int to = E[i].to;
            if(dis[to]>dis[u]+E[i].val){
                dis[to]=dis[u]+E[i].val;
                q.push(node(to,dis[to]));
            }
        }
    }
    return inf;
}
void init(){
    memset(vis, 0, sizeof(vis));
    for(int i=0; i<maxn; i++) dis[i]=inf;
    while(!q.empty()) q.pop();
}
LL work(int k)
{
    LL ans = inf;
    for(int i=0; i<20; i++){
        init();
        for(int j=1; j<=k; j++){
            if(a[j]&(1<<i)){
                q.push(node(a[j],0)),dis[a[j]]=0;
            }
            else{
                vis[a[j]]=1;
            }
        }
        ans = min(ans, Dijstra());
        init();
        for(int j=1; j<=k; j++){
            if(a[j]&(1<<i)){
                vis[a[j]]=1;
            }
            else{
                q.push(node(a[j],0)),dis[a[j]]=0;
            }
        }
        ans = min(ans, Dijstra());
    }
    return ans;
}
int T,n,m,k,ks;
int main()
{
    ks = 0;
    scanf("%d", &T);
    while(T--)
    {
        initedge();
        scanf("%d %d",&n,&m);
        for(int i=1; i<=m; i++){
            int u, v, w;
            scanf("%d %d %d", &u,&v,&w);
            add(u, v, w);
        }
        scanf("%d", &k);
        for(int i=1; i<=k; i++) scanf("%d", &a[i]);
        LL ans = work(k);
        printf("Case #%d: %lld\n", ++ks, ans);
    }
    return 0;
}

 

以上是关于2017多校第9场 HDU 6166 Senior Pan 堆优化Dij的主要内容,如果未能解决你的问题,请参考以下文章

2017多校第9场 HDU 6170 Two strings DP

2017全国多校第9场

2017多校第10场 HDU 6172 Array Challenge 猜公式,矩阵幂

2017多校第6场 HDU 6105 Gameia 博弈

2017多校第10场 HDU 6181 Two Paths 次短路

2017多校第10场 HDU 6180 Schedule 贪心,multiset