最短路模板

  1. floyd
    三重for循环+dp降维 适用范围:n<=500
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e3+10;
    int a[N][N],n,m,s;
    int u,v,w;
    int main()
    {
    	cin>>n>>m>>s;
    	memset(a,0x3f,sizeof(a));
    	while(m--)
    	{
    		cin>>u>>v>>w;
    		a[u][v]=min(a[u][v],w);
    	}
    	for(int k=1;k<=n;k++)
    	{
    		for(int i=1;i<=n;i++)
    		{
    			if(i==k||a[i][k]==0x3f3f3f3f)
    			{
    				continue;
    			}
    			for(int j=1;j<=n;j++)
    			{
    				a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
    			}
    		}
    	}
    	a[s][s]=0;
    	for(int i=1;i<=n;i++)
    	{
    		cout<<a[s][i]<<' ';
    	}
    	return 0;
    }
    //时间复杂度O(n^3)
  2. dijkstra
    //朴素版O(m+n^2)
    #include <bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int N=1e6+10;
    ll a[N],b[N],v[N];
    ll m,n,s,c,x,y,z;
    struct node
    {
    	ll x,y,z;
    }e[N];
    void add(ll x,ll y,ll z)
    {
    	c++;
    	e[c].x=y;
    	e[c].z=z;
    	e[c].y=a[x];
    	a[x]=c;
    }
    int main()
    {
    	cin>>m>>n>>s;
    	for(int i=1;i<=n;i++)
    	{
    		b[i]=INT_MAX;
    	}
    	b[s]=0;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>x>>y>>z;
    		add(x,y,z);
    	}
    	x=s;
    	while(v[x]==0)
    	{
    		y=INT_MAX;
    		v[x]=1;
    		for(int i=a[x];i!=0;i=e[i].y)
    		{
    			if(!v[e[i].x]&&b[e[i].x]>b[x]+e[i].z)
    			{
    				b[e[i].x]=b[x]+e[i].z;
    			}
    		}
    		for(int i=1;i<=m;i++)
    		{
    			if(b[i]<y&&v[i]==0)
    			{
    				y=b[i];
    				x=i;
    			}
    		}
    	}
    	for(int i=1;i<=m;i++)
    	{
    		cout<<b[i]<<' ';
    	}
    	return 0;
    }
    //堆优化O((n+m)logm)
    priority_queue<node> q;
    void dijkstra(int st)
    {
    	memset(d,0x3f,(n+1)*sizeof(int));
    	memset(vis,0,(n+1)*sizeof(int));
    	d[st]=0;q.push({st,0});
    	while(!q.empty())
    	{
    		int u=q.top().u;q.pop();
    		if(vis[u])continue;
    		vis[u]=1;
    		for(int i=head[u]; i; i=e[i].next)
    		{
    			int v=e[i].v,u=e[i].u;
    			if(d[v]>d[u]+e[i].w)
    			{
    				d[v]=d[u]+e[i].w;
    				q.push({v,d[v]});
    			}
    		}
    	}
    }
    
  3. spfa
    //O(nm)~O(m)
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int u,v,w,n,m,k;
    int d[N],f[N];
    queue<int>q;
    struct node
    {
    	int x,y;
    };
    vector<node>g[N];
    void spfa()
    {
    	q.push(k);
    	d[k]=0;
    	f[k]=1;
    	while(!q.empty())
    	{
    		u=q.front();
    		q.pop();
    		f[u]=0;
    		for(auto t:g[u])
    		{
    			v=t.x;
    			w=t.y;
    			if(d[v]>d[u]+w)
    			{
    				d[v]=d[u]+w;
    				if(!f[v])
    				{
    					q.push(v);
    					f[v]=1;
    				}
    			}
    		}
    	}
    }
    int main()
    {
    	memset(d,0x3f,sizeof(d));
    	cin>>n>>m>>k;
    	while(m--)
    	{
    		cin>>u>>v>>w;
    		g[u].push_back({v,w});
    	}
    	spfa();
    	for(int i=1;i<=n;i++)
    	{
    		if(d[i]==0x3f3f3f3f)
    		{
    			cout<<INT_MAX<<' ';
    		}
    		else
    		{
    			cout<<d[i]<<' ';
    		}
    	}
    	return 0;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值