A1018 Public Bike Management (30) 最短路径DFS+dijkstra

    技术2024-07-31  71

    本题是DFS+dijkstra算法的典型应用题,做本题前,需要认真读完题目(注意输出要求也会给出相应的判断)因为带去自行车,和拿回来的动作的都是实时发生的,不能用简单的加减计算,所以采用的使DFS+dijkstra的算法。最后判断部分条件,又因为此时是一半的容量为基准,所以可以考虑开始就将容量除以二

    #include<cstdio> #include<iostream> #include<vector> #include<cmath> const int maxn=1010; const int inf=0x3fffffff; using namespace std; int G[maxn][maxn],d[maxn], minneed=inf,minback=inf,n,m,ed,cmax,weight[maxn]; bool vis[maxn]={false}; vector<int> pre[maxn],path,temp; void dijkstra(int s) { fill(d,d+maxn,inf); d[s]=0; for(int i=0;i<=n;i++) { int min=inf,u=-1; for(int j=0;j<=n;j++) { if(vis[j]==false&&d[j]<min) { min=d[j]; u=j; } } if(u==-1)return; vis[u]=true; for(int v=0;v<=n;v++) { if(vis[v]==false&&G[u][v]!=inf) { if(G[u][v]+d[u]<d[v]) { pre[v].clear(); pre[v].push_back(u); d[v]=G[u][v]+d[u]; } else if(G[u][v]+d[u]==d[v]) { pre[v].push_back(u); } } } } } void DFS(int v) { if(v==0) { int need=0,back=0; temp.push_back(v); for(int i=temp.size()-1;i>=0;i--) { if(weight[temp[i]]>0) back+=weight[temp[i]]; else { if(back>abs(weight[temp[i]])) back=back-abs(weight[temp[i]]); else { need+=abs(weight[temp[i]])-back; back=0; } } } if(need<minneed) { minneed=need; minback=back; path=temp; } else if(need==minneed&&back<minback) { minback=back; path=temp; } temp.pop_back(); return; } temp.push_back(v); for(int i=0;i<pre[v].size();i++) { DFS(pre[v][i]); } temp.pop_back(); } int main() { int c1,c2,d; cin>>cmax>>n>>ed>>m; cmax/=2; for(int i=1;i<=n;i++) { scanf("%d",&weight[i]); weight[i]-=cmax; } fill(G[0],G[0]+maxn*maxn,inf); for(int i=0;i<m;i++) { scanf("%d %d %d",&c1,&c2,&d); G[c1][c2]=G[c2][c1]=d; } dijkstra(0); DFS(ed); printf("%d 0",minneed); for(int i=path.size()-2;i>=0;i--) { printf("->%d",path[i]); } printf(" %d",minback); }
    Processed: 0.012, SQL: 9