算法训练 最短路(spfa+slf优化)

来源:互联网 发布:淘宝宝贝重复铺货 编辑:程序博客网 时间:2024/05/21 18:33
问题描述
给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。
输入格式
第一行两个整数n, m。
接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。
输出格式
共n-1行,第i行表示1号点到i+1号点的最短路。
样例输入
3 3
1 2 -1
2 3 -1
3 1 2
样例输出
-1
-2
数据规模与约定
对于10%的数据,n = 2,m = 2。
对于30%的数据,n <= 5,m <= 10。

对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。

#include<cstdio>#include<iostream>#include<cstring>#include<queue>using namespace std;const int mn=20010,mm=200000+10;struct node{int to,w,next;}edge[mm];int n,m,head[mn],dis[mn];void spfa(){int vis[mn]={0};deque<int> Q;Q.push_back(1);vis[1]=1;memset(dis,0x3f3f3f3f,sizeof(dis));dis[1]=0;while(!Q.empty()){int t=Q.front();//cout<<"t: "<<t<<endl;Q.pop_front();vis[t]=0;for(int i=head[t];i!=-1;i=edge[i].next){int u=edge[i].to;if(dis[u]>dis[t]+edge[i].w){dis[u]=dis[t]+edge[i].w;if(!vis[u]){if(!Q.empty()&&dis[u]<dis[Q.front()])Q.push_front(u);else Q.push_back(u);vis[u]=1;}}}}}int main(){ios::sync_with_stdio(0);cin>>n>>m;int u,v,w;memset(head,-1,sizeof(head));for(int i=0;i<m;i++){cin>>u>>v>>w;edge[i].w=w;edge[i].to=v;edge[i].next=head[u];head[u]=i;}spfa();for(int i=2;i<=n;i++)cout<<dis[i]<<endl;return 0;}

#include<cstdio>#include<iostream>#include<cstring>#include<queue>using namespace std;int dis[20002],head[20002],n,m;bool vis[20002];struct node{int to,w,next;}edge[200002];void spfa(){int k,i,v;queue<int> Q;Q.push(1);vis[1]=1;dis[1]=0;while(!Q.empty()){k=Q.front();Q.pop();vis[k]=0;for(i=head[k];i!=-1;i=edge[i].next){v=edge[i].to;if(dis[v]>dis[k]+edge[i].w){dis[v]=dis[k]+edge[i].w;if(!vis[v]){vis[v]=1;Q.push(v);}}}}}int main(){int v1,v2,w,i;scanf("%d%d",&n,&m);memset(head,-1,sizeof(head));memset(vis,0,sizeof(vis));memset(dis,0x3f3f3f3f,sizeof(dis));for(i=1;i<=m;i++){scanf("%d%d%d",&v1,&v2,&w);edge[i].to=v2;edge[i].w=w;edge[i].next=head[v1];head[v1]=i;}spfa();for(i=2;i<=n;i++)printf("%d\n",dis[i]);return 0;}


原创粉丝点击