zoukankan      html  css  js  c++  java
  • 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
    ", ++ks, ans);
        }
        return 0;
    }
    
  • 相关阅读:
    基于storm和hadoop的广告系统研究【2】
    基于storm和hadoop的广告系统研究【1】
    签名ipa,让其它手机也安装
    UIWebview 截获html并修改内容。
    Resetting the SMC & PRAM
    UITableview 兼容IOS6 和IOS7的方法
    IOS7 APP 升级的10个TIP 建议
    IOS: Xcode报 Undecleared selector Warning错误的解决方法
    十个iOS面试问题
    iOS制作Static Library(静态库),实现多工程的连编
  • 原文地址:https://www.cnblogs.com/spfa/p/7417082.html
Copyright © 2011-2022 走看看