1. 程式人生 > 實用技巧 >1018 Public Bike Management (30分)

1018 Public Bike Management (30分)

1018Public Bike Management(30分)

#include<stdio.h>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=1010;
const int INF=1000000000;
int  cmax,n,sp,m;
int G[maxn][maxn],d[maxn];
int weight[maxn],w[maxn];
int minneed=INF,minremain=INF;
int vis[maxn]={0};
vector<int>path,temppath,pre[maxn];
void dijkstra(int s){
    fill(d,d+maxn,INF);
    d[s]=0;
    for(int i=0;i<=n;i++){             //注意這裡dijkstra都是n+1次~~~~~~~第一次寫的n導致一堆段錯誤
        int u=-1,min=INF;
        for(int j=0;j<=n;j++){
            if(vis[j]==0&&d[j]<min){
                u=j;
                min=d[j];
            }
        }
        if(u==-1)return;
        vis[u]=1;
        for(int v=0;v<=n;v++){
            if(vis[v]==0&&G[u][v]!=INF){
                if(d[u]+G[u][v]<d[v]){
                    d[v]=d[u]+G[u][v];
                    pre[v].clear();
                    pre[v].push_back(u);
                }
                else if(d[u]+G[u][v]==d[v]){
                    pre[v].push_back(u);
                }
            }   
        }
    }
}
void DFS(int v){
    if(v==0){
        temppath.push_back(v);
        int need=0,remain=0;
        for(int i=temppath.size()-1;i>=0;i--){
            int id=temppath[i];
            if(weight[id]>=0){
                remain+=weight[id];
            }
            else{
                if(remain+weight[id]>=0){
                    remain+=weight[id];
                }
                else{
                    need+=-(remain+weight[id]);
                    remain=0;
                }
            }
        }
        if(need<minneed){
            minneed=need;
            minremain=remain;
            path=temppath;
        }
        else if(need==minneed&&remain<minremain){
            minremain=remain;
            path=temppath;
        }
        temppath.pop_back();
        return;
    }
    temppath.push_back(v);
    for(int i=0;i<pre[v].size();i++){
        DFS(pre[v][i]);
    }
    temppath.pop_back();
}
int main()
{
    scanf("%d %d %d %d",&cmax,&n,&sp,&m);
    fill(G[0],G[0]+maxn*maxn,INF);
    int c;
    for(int i=1;i<=n;i++){
        scanf("%d",&c);
        weight[i]=c-cmax/2;
    }
    int a,b;
    for(int i=0;i<m;i++){
        scanf("%d %d",&a,&b);
        scanf("%d",&G[a][b]);
        G[b][a]=G[a][b];
    }
    dijkstra(0);
    DFS(sp);
    printf("%d ",minneed);
    for(int i=path.size()-1;i>0;i--){    //注意倒序輸出
        printf("%d->",path[i]);
    }
    printf("%d %d",path[0],minremain);
    return 0;
}