最短路径 | 1087 三重标尺+记录最短路径条数

这题可谓最短路的集大成。map或字符串hash的输入处理、多重标尺、最短路径条数。

但是这都是纸老虎,搞清楚逻辑和概念,所有问题迎刃而解。

代码是在宿舍写的。因为声音比较嘈杂,导致写了个很傻比的bug,调了很久。

 

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 1010
#define MAX (1<<30)-1
#define V vector<int>

using namespace std;

int g[LEN][LEN];
int vis[LEN];
int dist[LEN];
int pre[LEN];
int hap_s[LEN];
int hap[LEN];
int way_cnt[LEN];
int v_cnt[LEN];

map<string,int> name2id;
string id2name[LEN] ;
int nID=1;
int e;

int getID(string s){
    int i=name2id[s];
    if(i){
        return i;
    }else{
        if(s=="ROM")
            e=nID;
        name2id[s]=nID;
        id2name[nID]=s;
        return nID++;
    }
}

int main(){
//    freopen("I:\\pat\\最短路径\\1087.txt","r",stdin);
    int n,m,s,i,j,a,b,c;
    char buf[100];
    char str1[100];
    char str2[100];
    I("%d%d%s",&n,&m,buf);
    s=getID(buf);
    FF(i,n-1){
        I("%s%d",buf,&a);
        hap_s[getID(buf)]=a;
    }
    fill(g[0],g[0]+LEN*LEN,MAX);
    fill(dist,dist+LEN,MAX) ;
    FF(i,m){
        I("%s%s%d",str1,str2,&c);
        a=getID(str1);
        b=getID(str2);
        g[b][a]=g[a][b]=c;
    }
    dist[s]=0;
    hap[s]=hap_s[s];
    way_cnt[s]=1;
    pre[s]=-1;
    v_cnt[s]=0;
    while(1){
        int u=-1,d=MAX;
        F(i,1,nID) if(!vis[i] && dist[i]<d){
            d=dist[i];
            u=i;
        }
        if(u<0) break;
        vis[u]=1;
        F(i,1,nID) if(!vis[i]){
            if(dist[u]+g[u][i]<dist[i]){
                dist[i]=dist[u]+g[u][i];
                way_cnt[i]=way_cnt[u];
                //
                hap[i]=hap[u]+hap_s[i];
                pre[i]=u;
                v_cnt[i]=v_cnt[u]+1;
            }else if(dist[u]+g[u][i]==dist[i]){
                way_cnt[i]+=way_cnt[u];
                if(hap[u]+hap_s[i]>hap[i] || (hap[u]+hap_s[i]==hap[i] && v_cnt[u]+1<v_cnt[i])){
                    hap[i]=hap[u]+hap_s[i];
                    pre[i]=u;
                    v_cnt[i]=v_cnt[u]+1;
                }
            }
        }
    }
    vector<string> path;
    i=e;
    while(i>=0){
        path.insert(path.begin(),id2name[i]);
        i=pre[i];
    }
    printf("%d %d %d %d\n",way_cnt[e],dist[e],hap[e],hap[e]/v_cnt[e]);
    FF(i,path.size()){
        O("%s",path[i].c_str());
        if(i!=path.size()-1) O("->");
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/TQCAI/p/8527781.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值