【PAT】1018. Public Bike Management

来源:互联网 发布:mac优化 编辑:程序博客网 时间:2024/04/30 07:53

考查点:DFS递归,Dijkstra求最短路径

思路:这道题不能直接用Dijkstra来更新need和remain必须用DFS遍历所有最短路径才能更新,写Dijkstra记得判断vis[u]==false,路径用pre记录前驱节点,因为有多条最短路径,必须用Vector数组来保存,Dijkstra主要涉及的就是pre的更新,DFS每次递归到边界0处时候遍历temp路径计算need和remain,更新最小值和anspath,对于有多种相等情况的题注意看清题目有哪些变量要理清楚

#define LOCAL#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <string>#include <vector>#include <map>#include <set>#include <queue>#include <stack>#define FOR(i, x, y) for(int i = x; i <= y; i++)#define rFOR(i, x, y) for(int i = x; i >= y; i--)#define MAXN 600#define oo 0x3f3f3f3fusing namespace std;int G[MAXN][MAXN];int d[MAXN];int w[MAXN];int vis[MAXN];vector<int> pre[MAXN];vector<int> temp,path;int minNeed=oo,minRemain=oo;int c,n,sp,m;void Dijkstra(int s){    fill(d,d+MAXN,oo);    d[s]=0;    for(int i=0;i<=n;i++)    {        int MIN=oo;int u=-1;        for(int j=0;j<=n;j++)        {            if(d[j]<MIN&&vis[j]==false){                MIN=d[j];                u=j;            }        }        if(u==-1)return ;        vis[u]=true;        for(int v=0;v<=n;v++)        {            if(vis[v]==false&&d[u]+G[u][v]<d[v]){                pre[v].clear();                d[v]=d[u]+G[u][v];                pre[v].push_back(u);            }else if(vis[v]==false&&d[u]+G[u][v]==d[v]){               pre[v].push_back(u);            }        }    }}void DFS(int v){    if(v==0){        temp.push_back(v);        int need=0,remain=0;        for(int i=temp.size()-1;i>=0;i--){            int id=temp[i];            if(w[id]>0){                remain+=w[id];            }else{                if(remain>abs(w[id])){                    remain-=abs(w[id]);                }else{                    need+=abs(w[id])-remain;                    remain=0;                }            }        }        if(need<minNeed){            minNeed=need;            minRemain=remain;            path=temp;        }else if(need==minNeed&&remain<minRemain){            minRemain=remain;            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(){    #ifdef LOCAL        freopen("data.in","r",stdin);        freopen("data.out","w",stdout);    #endif // LOCAL    scanf("%d%d%d%d",&c,&n,&sp,&m);    fill(G[0],G[0]+MAXN*MAXN,oo);    FOR(i,1,n)    {        scanf("%d",&w[i]);        w[i]-=c/2;    }    FOR(i,1,m)    {        int u,v,w;        scanf("%d%d%d",&u,&v,&w);        G[u][v]=G[v][u]=w;    }    Dijkstra(0);    DFS(sp);    printf("%d ",minNeed);    for(int i=path.size()-1;i>=0;i--){        printf("%d",path[i]);        if(i>0)printf("->");    }    printf(" %d",minRemain);    return 0;}


0 0