码迷,mamicode.com
首页 > 其他好文 > 详细

1018 Public Bike Management (30 分)(图的遍历and最短路径)

时间:2018-12-16 19:28:15      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:遍历   部分   int   amp   +=   枚举   vector   span   alt   

技术分享图片

 

 

这题不能直接在Dijkstra中写这个第一 标尺和第二标尺的要求 因为这是需要完整路径以后才能计算的  所以写完后可以在遍历

 

#include<bits/stdc++.h>

using namespace std;
int cmax,n,v,m;
const int N=1e3;
int weight[N];
int mp[N][N];
const int inf=0x3f3f3f3f;
int dis[N];
int vis[N];
vector<int>path[N];
void Dijkstra()
{
    fill(dis,dis+N,inf);
    fill(vis,vis+N,false);
    for(int i=0;i<=n;i++) dis[i]=mp[0][i];
    dis[0]=0;
    for(int i=0;i<n;i++){
        int u=-1;
        int minn=inf;
        for(int j=0;j<=n;j++){
            if(!vis[j]&&minn>dis[j]){
                minn=dis[j];
                u=j;
            }
        }
        vis[u]=true;
        for(int j=0;j<=n;j++){
            if(!vis[j]&&dis[j]>=mp[u][j]+dis[u]){
                if(dis[j]>mp[u][j]+dis[u]){
                    dis[j]=mp[u][j]+dis[u];
                    path[j].clear();
                    path[j].push_back(u);
                }
                else if(dis[j]==mp[u][j]+dis[u]){
                    path[j].push_back(u);
                }
            }
        }
    }
}
vector<int>t,tt;
int minNeed=inf;
int minRemain=inf;
void dfs(int v)
{
    if(v==0){
        t.push_back(v);
        int need=0;//需要从0点带的车数
        int remain=0;//需要带回0点的车数
        for(int i=t.size()-1;i>=0;i--){//必须倒着枚举
            int id=t[i];
            if(weight[id]>0){// >0 说明需要带走一部分自行车
                remain+=weight[id];
            }
            else{//需要补给
                if(remain>abs(weight[id])){
                    remain-=abs(weight[id]);
                }
                else{
                    need+=abs(weight[id])-remain;
                    remain=0;
                }
            }
        }
        if(need<minNeed){//第一标尺
            minNeed=need;
            minRemain=remain;
            tt=t;
        }
        else if(need==minNeed&&remain<minRemain){//第二标尺
            minRemain=remain;
            tt=t;
        }
        t.pop_back();
        return;
    }
    t.push_back(v);
    for(int i=0;i<path[v].size();i++){
        dfs(path[v][i]);
    }
    t.pop_back();
}
int main()
{
    scanf("%d %d %d %d",&cmax,&n,&v,&m);
    fill(weight,weight+N,0);
    for(int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        weight[i]=x-cmax/2;
    }
    fill(mp[0],mp[0]+N*N,inf);
    for(int i=0;i<m;i++){
        int a,b,c;
        scanf("%d %d %d",&a,&b,&c);
        mp[a][b]=mp[b][a]=c;
    }
    Dijkstra();
    dfs(v);
    printf("%d ",minNeed);
    for(int i=tt.size()-1;i>=0;i--){
        if(i!=tt.size()-1) printf("->");
        printf("%d",tt[i]);
    }
    printf(" %d\n",minRemain);
    return 0;
}

 

1018 Public Bike Management (30 分)(图的遍历and最短路径)

标签:遍历   部分   int   amp   +=   枚举   vector   span   alt   

原文地址:https://www.cnblogs.com/chenchen-12/p/10127431.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!