#include<iostream> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int N=100010; int n,m; int h[N]; int ne[N];int e[N],w[N],idx=0; int dist[N]; bool st[N]; void add(int a,int b,int c) { ne[idx]=h[a];e[idx]=b;w[idx]=c;h[a]=idx++; } int spfa() { queue<int>q;//更新距离后的点就存起来,然后更新其邻接的点的距离 memset(dist,0x3f,sizeof dist); dist[1]=0; st[1]=true;//存的点标记,防止重复存 q.push(1); while(q.size()) { int t=q.front(); q.pop(); st[t]=false;//弹出后就不用标记了 for(int i=h[t];i!=-1;i=ne[i]) { int j=e[i]; if(dist[j]>dist[t]+w[i]) { dist[j]=dist[t]+w[i]; if(!st[j]) { q.push(j); st[j]=true;//注意存一个必须标记一个 } } } } return dist[n]; } int main() { memset(h,-1,sizeof h); scanf("%d%d",&n,&m); while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } int t=spfa(); if(t==0x3f3f3f3f) puts("impossible"); else printf("%d\n",t); return 0; }
判断是否存在负环
#include<iostream> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int N=2010; const int M=100010; int n,m; int h[N]; int ne[M];int e[M],w[M],idx=0; int dist[N]; int cnt[N];//对边数进行计数 bool st[N]; void add(int a,int b,int c) { ne[idx]=h[a];e[idx]=b;w[idx]=c;h[a]=idx++; } bool spfa() { queue<int>q;//更新距离后的点就存起来,然后更新其邻接的点的距离 memset(dist,0x3f,sizeof dist); dist[1]=0; for(int i=1;i<=n;i++)//把每个点都进队列,因为不确定是不是第一个点经过负环,所以全部遍历 { q.push(i); st[i]=true; } while(q.size()) { int t=q.front(); q.pop(); st[t]=false;//弹出后就不用标记了 for(int i=h[t];i!=-1;i=ne[i]) { int j=e[i]; if(dist[j]>dist[t]+w[i]) { dist[j]=dist[t]+w[i]; cnt[j]=cnt[t]+1; if(cnt[j]>=n) return false; if(!st[j]) { q.push(j); st[j]=true;//注意存一个必须标记一个 } } } } return true; } int main() { memset(h,-1,sizeof h); scanf("%d%d",&n,&m); while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } if(spfa()) puts("No"); else puts("Yes"); return 0; }
floyd
#include<iostream> #include<cstring> #include<algorithm> using namespace std; const int N=210, INF=1e9; int d[N][N]; int n,m,Q; void floyd()//算法关键 { for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=min(d[i][j],d[i][k]+d[k][j]); } int main() { scanf("%d%d%d",&n,&m,&Q); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(i==j) d[i][j]=0; else d[i][j]=INF; } while(m--) { int x,y,z; scanf("%d%d%d",&x,&y,&z); d[x][y]=min(d[x][y],z); } floyd(); while(Q--) { int a,b; scanf("%d%d",&a,&b); if(d[a][b]>=INF/2) puts("impossible");//可能存在负权边 else printf("%d\n",d[a][b]); } return 0; }
标签:11,dist,idx,int,短路,st,负环,return,include From: https://www.cnblogs.com/daimazhishen/p/17804131.html