zoukankan      html  css  js  c++  java
  • hdu 6166 Senior Pan

    http://acm.hdu.edu.cn/showproblem.php?pid=6166

    题意:

    给出一张无向图,给定k个特殊点

    求这k个特殊点两两之间的最短路

    二进制分组

    枚举一位二进制位

    这一位为1的放到起点集合

    这一位为0的放到终点集合

    跑一遍两个集合间的最短路

    因为是有向图,反过来再跑一遍

    正确性分析:

    设最优解是x和y间的最短路

    若x和y被分在了两个不同的集合,那么两个集合的最短路就是x和y的最短路

    而任意两个点至少有一位二进制不同

    所以一定会有x和y分在两个不同集合的时候

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 100001
    
    typedef long long LL;
    
    int n,k;
    
    int front[N],to[N],nxt[N],val[N],tot;
    
    int point[N];
    
    struct node
    {
        int id;
        LL dis;
    
        node(int id_=0,LL dis_=0):id(id_),dis(dis_){}
    
        bool operator < (node p) const
        {
            return dis>p.dis;
        }
    };
    priority_queue<node>q;
    
    bool End[N],vis[N];
    
    LL dis[N];
    LL ans;
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    void add(int u,int v,int w)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w;
    }
    
    void dijkstra()
    {
        node now;
        while(!q.empty())
        {
            now=q.top();
            q.pop();
            if(vis[now.id]) continue;
            vis[now.id]=true;
            for(int i=front[now.id];i;i=nxt[i])
                if(dis[now.id]+val[i]<dis[to[i]])
                {
                    dis[to[i]]=dis[now.id]+val[i];
                    if(End[to[i]]) ans=min(ans,dis[to[i]]);
                    else q.push(node(to[i],dis[to[i]]));
                }
        }
    }
    
    
    void solve()
    {
        int S,bit;
        for(S=1;(1<<S)-1<k;++S);
        for(int j=1;j<=S;++j)
        {
            bit=1<<j-1;
            memset(End,false,sizeof(End));
            memset(vis,false,sizeof(vis));
            memset(dis,63,sizeof(dis));
            for(int i=1;i<=k;++i)
            {
                if(point[i] & bit) q.push(node(point[i],0)),dis[point[i]]=0;
                else End[point[i]]=true;
            }
            dijkstra();
            memset(End,false,sizeof(End));
            memset(vis,false,sizeof(vis));
            memset(dis,63,sizeof(dis));
            for(int i=1;i<=k;++i)
            {
                if(!(point[i] & bit)) q.push(node(point[i],0)),dis[point[i]]=0;
                else End[point[i]]=true;
            }
            dijkstra();
        }
    }
        
    void clear()
    {
        tot=0;
        memset(front,0,sizeof(front));
        ans=1e18;
    }
    
    int main()
    {
        int T;
        int m;
        int u,v,w;
        read(T);
        for(int t=1;t<=T;++t)
        {
            clear();
            read(n); read(m);
            while(m--)
            {
                read(u); read(v); read(w);
                add(u,v,w);
            }
            read(k);
            for(int i=1;i<=k;++i) read(point[i]);
            solve();
            printf("Case #%d: %I64d
    ",t,ans);
        }
    }
  • 相关阅读:
    jvm
    深度学习 机器学习
    中小规模机器学习的问题
    threading.Condition()
    实现 TensorFlow 架构的规模性和灵活性
    随机条件场
    使用TensorFlow Serving优化TensorFlow模型
    PDB、PD、PMP、RTB哪个更好?为品牌主解锁程序化购买的选择技巧
    bisecting k-means
    内核futex的BUG导致程序hang死问题排查
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8426825.html
Copyright © 2011-2022 走看看