#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int N=2500;
int vis[N];
int mp[N][N];
int dis[N];
int n,m;
int s,e;
void dij()
{
int i,j,k,min,u;
for(i=1;i<=n;i++) //因为是从1开始
{
dis[i]=mp[s][i];//先把与1相连的所有的点的权值,都记录下来
} //不相连的那些点记录进去的是无穷,但不影响后面的判断,因为是找最小的,所以无穷不影响判断
vis[s]=1; //1点标记为走过了
dis[s]=0;
for(i=1;i<n;i++)//进行n-1次查询
{
min=inf;
for(j=1;j<=n;j++)
{
if(min>dis[j]&&!vis[j]) //那个点没被走过的情况下,开始找最小的权值,并把那个点记录下来
{
min=dis[j];
u=j;
}
}
vis[u]=1;//找到的那个点,标记走过了
for(k=1;k<=n;k++) //开始调整到n个点的权值
{
if(!vis[k]&&mp[u][k]<inf&&dis[k]>mp[u][k]+dis[u]) //在那个点没被走的情况下,从当前点能走到那个点的情况(废话,能走才会走过去)
{ //把当前记录的权值,与加入新点后走到那个点所需要的权值进行比较,记录小的那个
dis[k]=mp[u][k]+dis[u];
}
}
}
//printf("%d\n",point[n]); //最后输出走到n点需要的总权值
}
int main()
{
cin>>n>>m;
cin>>s>>e;
memset(mp,inf,sizeof(mp));
memset(vis,0,sizeof(vis));
memset(dis,inf,sizeof(dis));
for(int i=1;i<=n;i++)
mp[i][i]=0;
while(m--)
{
int u,v,w;
cin>>u>>v>>w;
if(mp[u][v]>w)
mp[u][v]=mp[v][u]=w;
}
dij();
cout<<dis[e];
return 0;
}
---------------------------------
最小生成树
#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
const int N=1e5;
#define inf 0x3f3f3f3f
struct edge
{
int v,w;
};
vector<edge>g[N];
int n,m;
int dis[N];
int sum;
bool vis[N];
void prim()
{
dis[1]=0;
int min,k;
for(int i=1;i<=n;i++)
{
min=inf;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&dis[j]<min)
{
min=dis[j];
k=j;
}
}
vis[k]=1;
for(auto ed:g[k])
{
int v=ed.v;int w=ed.w;
if(!vis[v]&&dis[v]>w)
dis[v]=w;
}
sum+=dis[k];
}
return ;
}
int main()
{
while(cin>>n>>m)
{
sum=0;
memset(vis, 0, sizeof(vis));
memset(dis, inf, sizeof(dis));
for(int i=1;i<=n;i++)
g[i].clear();
for(int i=0;i<m;i++)
{
int u,v,w;
cin>>u>>v>>w;
g[u].push_back(edge({v,w}));
g[v].push_back(edge({u,w}));
}
prim();
cout<<sum<<endl;
}
return 0;
}
J - 热浪(朴素版)dij与朴素版最小生成树
最新推荐文章于 2024-08-13 14:56:59 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)