【题目描述】
工厂为了生产一种复杂的产品,给各个生产部门制定了详细的生产计划。那么,就经常会有生产部门要把产品送到另一个生产部门作为原料。这是一个注重产品质量的工厂,所以每当有产品要从A部门运到B部门时,都要先从A部门送到质量检验处,检验合格后再从质量检验处运到B部门。
有些部门之间有传送带连接,厂长想知道每次将产品从一个部门运送到另一个部门最少需要多长时间。
【输入格式】
第一行两个整数n、m,n表示部门数量,m表示传送带数量。出于方便,1号部门是质量检验处。
接下来m行,每行三个整数u、v、w,表示有一条从u部门到v部门的传送带,传送过去需要w个单位时间。注意传送带是单向的。
接下来一个整数q,表示有q次运送。
接下来q行,每行两个数a、b,表示这一次要将产品从a部门运送到b部门。
【输出格式】
输出q行,每行一个整数,表示这次运送最少需要的时间。若没有传送方案,输出-1。
【样例输入】
5 5
1 2 3
1 3 5
4 1 7
5 4 1
5 3 1
3
4 2
5 3
2 3
【样例输出】
10
13
-1
【数据规模与约定】
30%的数据,n≤100,m≤500,w=1
60%的数据,n≤100,m≤5000
另20%的数据,q=1
100%的数据,2≤n≤3000,m≤100000,2≤a,b≤n,
q≤100000,1≤u,v≤n,1≤w≤10000
有些部门之间可能有多条传送带。
工厂的员工都非常尽职尽责,他们的认真和热情决定了产品的完美,所以不必考虑产品不合格的情况。
分别以1为起点和以1为终点跑一边最短路。
我是用的点。
题解是用的边。
大概敲了半个小时。
代码实现:
mine:
1 #include<cstdio> 2 #include<iostream> 3 #define inf 30000010 4 using namespace std; 5 int n,m,q; 6 int map[3010][3010],v[3010],w[3010]; 7 int a,b,c,pa,pb,na,nb; 8 bool vv[3010],ww[3010]; 9 int main(){ 10 freopen("production.in","r",stdin); 11 freopen("production.out","w",stdout); 12 scanf("%d%d",&n,&m); 13 for(int i=1;i<=n;i++) 14 for(int j=1;j<=n;j++) 15 if(i!=j) map[i][j]=inf; 16 for(int i=0;i<m;i++){ 17 scanf("%d%d%d",&a,&b,&c); 18 map[a][b]=min(map[a][b],c); 19 } 20 for(int i=2;i<=n;i++) v[i]=w[i]=inf; 21 a=b=1;vv[1]=ww[1]=1; 22 for(int k=0;k<n;k++){ 23 pa=pb=inf;na=nb=0; 24 if(a) for(int i=1;i<=n;i++){ 25 v[i]=min(v[i],v[a]+map[a][i]); 26 if(!vv[i]&&v[i]<pa){pa=v[i];na=i;} 27 } 28 if(b) for(int i=1;i<=n;i++){ 29 w[i]=min(w[i],w[b]+map[i][b]); 30 if(!ww[i]&&w[i]<pb){pb=w[i];nb=i;} 31 } 32 vv[na]=ww[nb]=1;a=na;b=nb; 33 } 34 scanf("%d",&q); 35 for(int i=1;i<=q;i++){ 36 scanf("%d%d",&a,&b); 37 if(v[b]==inf||w[a]==inf) printf("-1 "); 38 else printf("%d ",v[b]+w[a]); 39 } 40 return 0; 41 }
std:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N = 3050; 6 const int M = 500050; 7 const int inf = 987654321; 8 int n,m,q; 9 struct Edge 10 { 11 int u,v,w; 12 }xu[M]; 13 int point[N],to[M],next[M],val[M]; 14 int dui[N],mina[N],minb[N],top,tail; 15 bool indui[N]; 16 void MakeMinLen(int x[]) 17 { 18 int i; 19 dui[1]=1; 20 top=0;tail=1; 21 indui[1]=1; 22 for(i=1;i<=n;i++) 23 x[i]=inf; 24 x[1]=0; 25 while(top^tail) 26 { 27 top++; 28 if(top==N) 29 top=0; 30 int now=dui[top]; 31 int then=point[now]; 32 indui[now]=0; 33 while(then) 34 { 35 int tox=to[then]; 36 if(x[tox]>x[now]+val[then]) 37 { 38 x[tox]=x[now]+val[then]; 39 if(!indui[tox]) 40 { 41 indui[tox]=1; 42 tail++; 43 if(tail==N) 44 tail=0; 45 dui[tail]=tox; 46 } 47 } 48 then=next[then]; 49 } 50 } 51 } 52 void InitGraph() 53 { 54 int i; 55 scanf("%d%d",&n,&m); 56 for(i=1;i<=m;i++) 57 scanf("%d%d%d",&xu[i].u,&xu[i].v,&xu[i].w); 58 memset(point,0,sizeof point); 59 for(i=1;i<=m;i++) 60 { 61 next[i]=point[xu[i].v]; 62 point[xu[i].v]=i; 63 to[i]=xu[i].u; 64 val[i]=xu[i].w; 65 } 66 MakeMinLen(mina); 67 memset(point,0,sizeof point); 68 for(i=1;i<=m;i++) 69 { 70 next[i]=point[xu[i].u]; 71 point[xu[i].u]=i; 72 to[i]=xu[i].v; 73 val[i]=xu[i].w; 74 } 75 MakeMinLen(minb); 76 } 77 void MakeAns() 78 { 79 scanf("%d",&q); 80 while(q--) 81 { 82 int a,b; 83 scanf("%d%d",&a,&b); 84 int res=mina[a]+minb[b]; 85 if(res>=inf) 86 res=-1; 87 printf("%d ",res); 88 } 89 } 90 int main() 91 { 92 freopen("production.in","r",stdin); 93 freopen("production.out","w",stdout); 94 InitGraph(); 95 MakeAns(); 96 return 0; 97 }
其实,如果卡空间的话,我会MLE的。