开始用dijkstra直接求,发现不行,算法问题(1-2,(30),2-4(20),1--3(10),3--4(100)最后一个点无法更新,导致错误),后用取负,加大数法也没过。
现在(寒假了):求负权的(无负环),或者最长路(一样,取负求最短),不可以dijkstra,用 spfa可以
#include<iostream> //spfa #include<cstdio> #include<cstring> #include<queue> using namespace std; int a[200][200];int point[200];int pre[200];int mark[200];int d[200]; const int inf=0x3f3f3f3f; int main() { int t; cin>>t; int i; for(int ii=1;ii<=t;ii++) { int n,m; memset(a,0x3f,sizeof(a)); memset(d,0x3f,sizeof(d)); memset(point,0,sizeof(point)); memset(pre,0,sizeof(pre)); memset(mark,0,sizeof(mark)); cin>>n; for(i=1;i<=n;i++) { scanf("%d",&point[i]); } point[n+1]=0; cin>>m; int s,l; for(i=1;i<=m;i++) { scanf("%d%d",&s,&l); a[s][l]=-point[l]; } bool flag=1; d[1]=0; int cur=1; mark[cur]=1; queue<int>q; q.push(1); while(!q.empty()) { int cur=q.front(); q.pop(); for(i=1;i<=n+1;i++) { if(mark[i]==0&&d[cur]+a[cur][i]<d[i]) //可以松弛的要入队 { q.push(i); pre[i]=cur; } if(d[cur]+a[cur][i]<d[i]) //对所有的能松弛的松弛 d[i]=d[cur]+a[cur][i]; } } if(d[n+1]==inf) //防止出现无法到达 { printf("CASE %d# points : %d ",ii,d[n+1]); printf("circuit : 1->1"); if(ii==t)cout<<endl; else cout<<endl<<endl; continue; } int bb[205];int kk=n+1;int yy=1; while(pre[kk]!=1) { bb[yy++]=pre[kk]; kk=pre[kk]; } yy--; bb[0]=1; printf("CASE %d# points : %d ",ii,-d[n+1]); printf("circuit : 1"); for(i=yy;i>=0;i--) printf("->%d",bb[i]); if(ii==t)cout<<endl; else cout<<endl<<endl; } return 0; }