[Code+#4]最短路
[+#4]最短路#
链接:https://www.luogu.com.cn/problem/P4366
题面:给定一个个点,条边的无向图,若任意点对之间还有一条长为的边,求到的最短路。
题解:这个式子看似很毒瘤,实际上我们可以把每一位拆开来看,若要从走到:
上述等式的含义即为等价于
推广即得,任意的边,都可以被拆成若干个的边的权值和,每一个点向连边即可。
#include<iostream>
#include<queue>
using namespace std;
struct node
{
int v,data,nxt;
};
struct reads
{
int num,data;
bool operator < (const reads &a)const
{
return data>a.data;
}
};
reads tmp;
priority_queue<reads>q;
node edge[4000001];
int head[200001],len,dis[200001],n,m,C;
bool used[200001];
void add(int x,int y,int z)
{
edge[++len].v=y;
edge[len].data=z;
edge[len].nxt=head[x];
head[x]=len;
return;
}
reads make_reads(int x,int y)
{
tmp.num=x;
tmp.data=y;
return tmp;
}
void dijkstra(int x)
{
q.push(make_reads(x,0));
for (int i=0;i<=n;++i)
dis[i]=(i!=x)*1e9;
int top;
while (!q.empty())
{
top=q.top().num;
q.pop();
if (used[top])
continue;
used[top]=1;
for (int i=head[top];i>0;i=edge[i].nxt)
if (dis[edge[i].v]>dis[top]+edge[i].data)
{
dis[edge[i].v]=dis[top]+edge[i].data;
q.push(make_reads(edge[i].v,dis[edge[i].v]));
}
}
}
int main()
{
int x,y,z,A,B;
cin>>n>>m>>C;
for (int i=1;i<=m;++i)
{
cin>>x>>y>>z;
add(x,y,z);
}
for (int i=0;i<=n;++i)
for (int k=1;k<=2*n;k*=2)
if ((i^k)<=n)
add(i,i^k,k*C);
cin>>A>>B;
dijkstra(A);
cout<<dis[B]<<endl;
return 0;
}
作者:zhouhuanyi
出处:https://www.cnblogs.com/zhouhuanyi/p/16983594.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架