P1576 最小花费

原题链接

1.审题

1.使得转账后 B 收到 100 元。
2.互相转账
3. z%的手续费(z<100)

2.思路

1.dijkstra算法(很讨厌这种算法名字):把已探访过的点的下一个点中“ ‘还没探访过的点’的更新”放进堆里,堆里弹出未探访点的第一个更新便是该点的最值
2.准备工作,把所有的边放进树形链表(我觉得叫跳跃型更形象)里,对于链表中的每一个元素,都有head(同属于一个起点的、先一步放进去的、并列的边的下标),to(边的终点),cost(边的值),latest(最后一个放入链表中的以该点为起点的边的下标)
3.struct的重载比较符

3.代码

#include<bits/stdc++.h>
using namespace std;

struct
{
    int to;
    double cost;
    int head;
}way[200005];
int latest[2005]={0};
int len=0;

void add(int x,int y,double c)
{
    way[++len].to=y;
    way[len].cost=c;
    way[len].head=latest[x];
    latest[x]=len;
}

struct unit
{
    int pos;
    double renew;
    bool operator<(const unit &b)const
    {
        return b.renew<renew;
    }
};

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int x,y;
        double c;
        scanf("%d%d%lf",&x,&y,&c);
        add(x,y,c);
        add(y,x,c);
    }

    int A,B;
    scanf("%d%d",&A,&B);
    priority_queue<unit> q;
    int vis[2005]={0};
    double pay[2005]={0};
    q.push(unit{B,100.0});
    while(!q.empty())
    {
        int now=q.top().pos;
        double val=q.top().renew;
        q.pop();
        if(!vis[now])
        {
            vis[now]=1;
            pay[now]=val;
            for(int i=latest[now];i!=0;i=way[i].head)
            {
                int next=way[i].to;
                if(!vis[next])q.push(unit{next,pay[now]/(1-way[i].cost*1.0/100)});
            }
            //printf("%d: %.8lf\n",now,pay[now]);
        }
    }
    printf("%.8lf\n",pay[A]);
    return 0;
}

posted @   纯粹的  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示