問題描述 給定一個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#include #include #include #include
#include #define MAXINT 100000000 #define N 20001 using namespace std; struct eg{ int e; int w; }; int p[N]; bool flag[N]; vector v[N]; int plint[N]; vector pl; int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ p[i] = MAXINT; } for(int i=1;i<=m;i++){ int t1,t2,t3; eg ve; scanf("%d%d%d",&t1,&t2,&t3); ve.e = t2; ve.w = t3; v[t1].push_back(ve); if(t1==1){ p[t2] = t3; pl.push_back(t3); plint[pl.size()] = t2; } } for(int i=2;i<=n;i++){ int minN = MAXINT; int tt = 0; int index = 0; vector ::iterator iteri = pl.begin(); vector ::iterator rem; for(int j=0;iteri!=pl.end();iteri++,j++){ int tint = *iteri; if(tint ::iterator iter = v[tt].begin(); while(iter!=v[tt].end()){ int ee = iter->e; int ww = iter->w; if(p[ee]==MAXINT){ p[ee] = p[tt]+ww; pl.push_back(p[ee]); plint[pl.size()] = ee; } else if(p[ee]>p[tt]+ww){ int k; for(k=1;k<=pl.size();k++){ if(p[k]==ee) break; } p[ee] = p[tt]+ww; pl[k] = p[ee]; } iter++; } } for(int i=2;i<=n;i++){ printf("%d\n",p[i]); } return 0; }