求从第0层(只有一个起点)到顶层(有多个点)的最短路
特殊样例:
2 2 0 // 这个节点和根不连通 1 2 0 * 2 1 1 0 2 3 0 answer 5
这道题可以先建图再求最短路,也可以用dp
dp :
dp[i][j]表示到达第i层第j个节点的最短距离,第i层只能从i-1层爬上来,状态转移方程:
dp[i][j] = min(dp[i-1][j所连接的节点]+cost)
最后输出dp[顶层][]中最小的值即可
for(int i=1;i<=n;i++){ int k;cin>>k; vector<int> v(k,1111111); // 注意这里初始化为无穷大不可达,否则上面的样例不能通过 for(int j=0;j<k;j++){ int dis,pre; while(cin>>pre && pre!=0){ cin>>dis; if(s[i-1][pre-1]+dis<v[j]) v[j]=s[i-1][pre-1]+dis; } } s.push_back(v); char ch; if(i!=n) cin>>ch; }
另外由于第i-1层更新完第i层后就没用了,所以每次维护一层的最短路即可。
s[0]=1;s[1]=0; for(int i=1;i<=n;i++){ int k; scanf("%d", &k); temp[0] = k; for(int j=1;j<=k;j++) temp[j] = MAX; for(int j=1;j<=k;j++){ while( scanf("%d",&pre) && pre){ scanf("%d",&dis); // printf("j=%d temp=%d pre=%d dist=%d",j,temp[j],s[pre],dis); if(temp[j]>s[pre]+dis) temp[j]=s[pre]+dis; } } if(i!=n) scanf(" %c",&ch); for(int j=0;j<=temp[0];j++)s[j]=temp[j]; } // find min(s[1],...,s[ s[0] ]); ans = s[1]; for(int i=2;i<=s[0];i++){ if(s[i]<ans) ans=s[i];} printf("%d ", ans);
另外建图的代码:
cin >> depth; // init for(int i=0;i<maxn;++i) for(int j=0;j<maxn;++j) m[i][j]=inf; // read and construct matrix graph int id1=0,id2=1; // id1 is high,id2 is lower int num,index,value,upid,lowid; for(int i=0;i<depth;++i){ cin >> num; for(int j=0;j<num;++j){ while(cin>>index&&index){ cin >> value; //cout << j << " id2=" << id2 << endl; //cout << index << " id1=" << id1 << endl; upid = j + id2; lowid = index-1 + id1; m[lowid][upid]=value; } } id1=id2; id2+=num; n = id2; // printm(); char ch ; if(i<depth-1) cin >> ch; }
完整代码 : https://github.com/Iytz/algorithm/blob/master/graph/like_1G.cpp