zoukankan      html  css  js  c++  java
  • 牛妹游历城市(最短路补题

    题目传送门

    示例1

    输入

    2
    6
    2 3 5 8 13 21
    12
    1 2 3 4 5 6 7 8 9 10 11 12

    输出

    3
    5
    示例2

    输入 

    5
    3
    1 2 3
    4
    177 188 199 211
    2
    1 2
    4
    1 1 1 1
    5
    1 2 4 8 16

    输出 

    1
    1
    Impossible
    1
    Impossible


    第一次遇到建虚点做中介的题(绝不是因为是个废物而懒得刷题)。首先考虑暴力建路径,n2的复杂度明显超时。考虑二进制优化,对32个二进制位建32个虚点,对于每个点如果该点二进制第 j 位为1,则该点的与虚点的边权值为 1<<j。虚点指向实点的边权为 0。
    跑一个最后dijkstra即可。
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int qs=1e5+500;
     5 const ll inf=1e18;
     6 ll T,n,d[qs];
     7 bool u[qs];
     8 struct node{
     9     int y; ll p;
    10     node(){}
    11     node(int y,ll p):y(y),p(p){};
    12     /*bool operator < (const node &tem) const{
    13         return y>tem.y;
    14     }*/            
    15     //    本来想重载运算符将优先队列变成小根对,出了点问题 qwq 
    16 }t;
    17 
    18 vector<node> vc[qs];        // 不会链式前向星 qwq 
    19 priority_queue<pair <ll,int > > q;
    20 
    21 void dijkstra(){
    22     q.push(make_pair(0,1));
    23     while(q.size()){
    24         int x=q.top().second; q.pop();    //取出堆顶 
    25         if(u[x]) continue; u[x]=true;
    26         for(int i=0;i<vc[x].size();++i){    //访问每一个相邻节点 
    27             int y=vc[x][i].y;ll p=vc[x][i].p;
    28             if(d[y]>d[x]+p){
    29                 d[y]=d[x]+p;            //更新最短路 
    30                 q.push(make_pair(-d[y],y));        //pair第一维dist相反数,变成小根堆 
    31             }
    32         }    
    33     }
    34 }
    35 int main(){
    36     cin>>T;
    37     while(T--){
    38         cin>>n; ll  fx;
    39         // 初始化 
    40         for(int i=0;i<=n+200;++i) d[i]=inf,vc[i].clear(); d[1]=0;
    41         memset(u,false,sizeof(u));
    42         for(int i=1;i<=n;++i){
    43             cin>>fx;
    44             for(int j=0;j<=31;++j){
    45                 if(fx & (1ll<<j)){    //与虚点建边 
    46                     ll a=1ll<<j;
    47                     vc[i].push_back(node(n+j+1,a));
    48                     vc[n+1+j].push_back(node(i,0));
    49                 }
    50             }
    51         }
    52         dijkstra();
    53         if(d[n]>=inf) cout<<"Impossible
    ";
    54         else cout<<d[n]<<"
    ";
    55     }
    56     return 0;
    57 }

    //老废宅了.jpg

    it(5)=lowbit((101)2)=1, lowbit(8)=lowbit((1000)2)=8

  • 相关阅读:
    分类汇总统计mysql数据库一个字段中不同的记录的总和
    golang 基础知识4
    golang 基础知识3
    golang 基础知识2
    golang 基础知识1
    mysql 锁
    node child_process
    go get下载被墙的包
    mac 修改root的密码
    ali
  • 原文地址:https://www.cnblogs.com/Suki-Sugar/p/13557194.html
Copyright © 2011-2022 走看看