$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 */
多出来的代码是愚人节Codeforces吸猫的错误方式。