zoukankan      html  css  js  c++  java
  • 「CodePlus 2018 4 月赛」最短路

    $n leq 100000$,$m leq 500000$的有向图,两点之间还可以以$a xor b$的代价从$a$到$b$,问$s$到$t$的最短路。

    被自己蠢哭QAQ

    首先两个点之间不走给定的边,最短路一定是直接$s$到$t$,因为一个二进制的差异至少要被算一次。观察$s$到$t$的过程,可以把这个过程完全等价地变成:一次只改一个二进制位,代价完全不变。因此$xor$的边只用连$nlog_2(n)$条,然后就无脑最短路了。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<queue>
     5 //#include<vector>
     6 #include<algorithm>
     7 //#include<iostream>
     8 //#include<assert.h>
     9 using namespace std;
    10 
    11 int n,m,C,s,t;
    12 #define maxn 200011
    13 #define maxm 3500011
    14 struct Edge{int to,next,v;}edge[maxm]; int first[maxn],le=2;
    15 void in(int x,int y,int v) {Edge &e=edge[le]; e.to=y; e.v=v; e.next=first[x]; first[x]=le++;}
    16 
    17 #define LL long long
    18 LL dis[maxn];
    19 struct qnode
    20 {
    21     LL d; int id;
    22     bool operator > (const qnode &b) const {return d>b.d;}
    23 };
    24 priority_queue<qnode,vector<qnode>,greater<qnode> > q;
    25 void dijkstra()
    26 {
    27     for (int i=0;i<n;i++) dis[i]=1e18;
    28     dis[s]=0; q.push((qnode){0,s});
    29     while (!q.empty())
    30     {
    31         qnode now=q.top(); q.pop();
    32         if (now.d!=dis[now.id]) continue;
    33         for (int i=first[now.id];i;i=edge[i].next)
    34         {
    35             Edge &e=edge[i];
    36             if (dis[e.to]>now.d+e.v)
    37             {
    38                 dis[e.to]=now.d+e.v;
    39                 q.push((qnode){dis[e.to],e.to});
    40             }
    41         }
    42     }
    43 }
    44 
    45 int main()
    46 {
    47     scanf("%d%d%d",&n,&m,&C);
    48     {int tmp=1; while (tmp<=n) tmp<<=1; n=tmp;}
    49     for (int i=0;i<n;i++)
    50         for (int j=0;j<20;j++)
    51         {
    52             int k=i^(1<<j);
    53             if (k<n) in(i,k,(1<<j)*C);
    54         }
    55     for (int i=1,x,y,v;i<=m;i++) scanf("%d%d%d",&x,&y,&v),in(x,y,v);
    56     scanf("%d%d",&s,&t);
    57     dijkstra(); printf("%lld
    ",dis[t]);
    58     return 0;
    59 }
    60 
    61 /* 
    62 string s;
    63 string ss[10]; bool vis[10];
    64 int main()
    65 {
    66     ss[0]="no";
    67     ss[1]="no";
    68     ss[2]="no";
    69     ss[3]="no way";
    70     ss[4]="no way";
    71     ss[5]="dont even";
    72     ss[6]="are you serious";
    73     ss[7]="go die in a hole";
    74     ss[8]="worse";
    75     ss[9]="terrible";
    76     bool flag=1;
    77     for (int i=0;i<=9;i++)
    78     {
    79         cout<<i<<endl;
    80         getline(cin,s);
    81         bool f=0;
    82         for (int j=0;j<=9;j++) if (!vis[j] && s==ss[j]) {vis[j]=1; f=1; break;}
    83         if (!f) {flag=0; break;}
    84     }
    85     int cnt=0;
    86     for (int j=0;j<=9;j++) if (vis[j]) cnt++;
    87     if (cnt>=7) while (1); 
    88     if (flag) puts("grumpy");
    89     else puts("normal");
    90 //    puts("normal");
    91     return 0;
    92 }
    93 */ 
    View Code

    多出来的代码是愚人节Codeforces吸猫的错误方式。

  • 相关阅读:
    POJ 3630 Phone List/POJ 1056 【字典树】
    HDU 1074 Doing Homework【状态压缩DP】
    POJ 1077 Eight【八数码问题】
    状态压缩 POJ 1185 炮兵阵地【状态压缩DP】
    POJ 1806 Manhattan 2025
    POJ 3667 Hotel【经典的线段树】
    状态压缩 POJ 3254 Corn Fields【dp 状态压缩】
    ZOJ 3468 Dice War【PD求概率】
    POJ 2479 Maximum sum【求两个不重叠的连续子串的最大和】
    POJ 3735 Training little cats【矩阵的快速求幂】
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8696571.html
Copyright © 2011-2022 走看看