标签:+# Code dij int st vis P4366 1000 dis
by luogu
这是一张完全图,如果我们把所有的边以及他的特殊边连上肯定是要爆的。( $ n^2 + m $直接起飞
.观察完全图边权的性质,是异或!比如从1走到
我们可以把每个边按照类似二的方的方式来连边,比如0向1,2,4,8...以此类推(注意一共有n个点,所以判一下边界,这样每个点就是向外连log条了
1001 ->1000
1001^1000 -> 0001
想要从0000到1111的话(因为是异或),可以过0001,0010,0100,1000
这个样子,其他就是普通dij了
qwq
#include<bits/stdc++.h> #define int long long using namespace std; const int inf=2147483647; const int N=4e6+7; int n,m,c; int _; int head[N>>3],nxt[N<<1],to[N<<1],edge[N<<1]; void add(int x,int y,int z) { _++; nxt[_]=head[x]; head[x]=_; to[_]=y; edge[_]=z; return ; } void addedges() { for(int i=0;i<=n;i++) { for(int j=1;j<=n;j<<=1) { if((i^j)>n) continue; add(i,i^j,c*j); } } return ; } int vis[N],dis[N]; void dij(int s) { priority_queue<pair<int ,int > >q; q.push({0,s}); memset(dis,0x3f,sizeof(dis)); dis[s]=0; while(!q.empty()) { int x=q.top().second; q.pop(); if(vis[x]) continue; vis[x]=1; for(int i=head[x];i;i=nxt[i]) { int y=to[i]; if(dis[y]>dis[x]+edge[i]) { dis[y]=dis[x]+edge[i]; q.push({-dis[y],y}); } } } return ; } int st,ed; signed main() { ios::sync_with_stdio(false); cin>>n>>m>>c; addedges(); for(int i=1;i<=m;i++) { int x,y,z; cin>>x>>y>>z; add(x,y,z); } cin>>st>>ed; dij(st); cout<<dis[ed]; return 0; }
标签:+#,Code,dij,int,st,vis,P4366,1000,dis 来源: https://www.cnblogs.com/Hehe-0/p/15392732.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。