2025天梯训练1

PTA | L3-1 直捣黄龙 30分

思路:多关键字最短路,同时还要记录最短路径条数。

typedef struct node{
    int from,d,pass,kl;
    bool operator<(const node &x)const{
        if(d!=x.d) return d>x.d;
        if(pass!=x.pass) return pass ha;
unordered_map antHa;
int enemys[205];
int idx=0;
vector> vct[205];
int dis[205];       // 到达i城镇的最短路
int pass[205];      // 到达i城镇经过了多少城镇
int kl[205];      // 到达i城镇杀了多少人
int road[205];    // 当前城镇从哪来
int cnt[205];     // 到达i城镇的最短路条数
bool vis[205];
void dijkstra(int s){
    for(int i=0;i<=idx;i++) dis[i]=LONG_LONG_MAX/2;
    dis[s]=0,pass[s]=0,kl[s]=0,cnt[s]=1;
    priority_queue pq;
    pq.emplace(node{s,0,0,0});
    while(!pq.empty()){
        int from=pq.top().from;
        pq.pop();
        if(vis[from]) continue;
        vis[from]=true;
        for(auto v:vct[from]){
            int to=v.first,w=v.second;
            if(dis[to]>dis[from]+w){    // 距离更短
                dis[to]=dis[from]+w;
                pass[to]=pass[from]+1;
                kl[to]=kl[from]+enemys[to];
                road[to]=from;
                cnt[to]=cnt[from];
                pq.emplace(node{to,dis[to],pass[to],kl[to]});
            }
            else if(dis[to]==dis[from]+w){
                cnt[to]+=cnt[from];
                if(pass[to]>n>>m;
    cin>>home>>en;
    ha[home]=++idx;
    antHa[idx]=home;
    for(int i=1;i<=n-1;i++){
        string town; cin>>town;
        if(ha[town]==0) ha[town]=++idx,antHa[idx]=town;
        int x; cin>>x;
        enemys[ha[town]]=x;
    }
    for(int i=1;i<=m;i++){
        string t1,t2; cin>>t1>>t2;
        int d; cin>>d;
        vct[ha[t1]].e(ha[t2],d);
        vct[ha[t2]].e(ha[t1],d);
    }
    dijkstra(ha[home]);
    int cur=ha[en];
    stack stk;
    while(cur!=1){
        stk.emplace(antHa[cur]);
        cur=road[cur];
    }
    cout<"<

PTA | L3-2 拼题A打卡奖励  30分


 

思路:背包问题,但是要优化:

curSum+=minute[i];        // 不必每次都从m开始转移,这样很白白跑很多不必要的循环..学到了
curSum=min(curSum,m);     // 细节!@!

void solve(){
//    cout<<365*24*60*1000;    // 5e8
    int n,m; cin>>n>>m;
    int minute[1003]={0};
    int coin[1003]={0};
    for(int i=1;i<=n;i++) cin>>minute[i];
    for(int i=1;i<=n;i++) cin>>coin[i];
    vector dp(m+5,0);
    int ans=0,curSum=0;
    for(int i=1;i<=n;i++){
        curSum+=minute[i];        // 不必每次都从m开始转移,这样很白白跑很多不必要的循环..学到了
        curSum=min(curSum,m);     // 细节!@!
        for(int j=curSum;j>=minute[i];j--){
            dp[j]=max(dp[j],dp[j-minute[i]]+coin[i]);
            ans=max(ans,dp[j]);
        }
    }
    cout<

你可能感兴趣的:(c++,多关键字最短路)