ZOJ

题目:

有N-1个城市给首都(第N个城市)支援物资,有M条路,走每条路要耗费一定百分比(相对于这条路的起点的物资)的物资。问给定N-1个城市将要提供的物资,和每条路的消耗百分比。求能送到首都的最多的物资数量。

思路:

可以将这条路的对物资的消耗百分比转换为走过后留下的百分比,然后对这些路跑最长路。

#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <iomanip>
#define MAX 1000000000
#define inf 0x3f3f3f3f
#define FRE() freopen("in.txt","r",stdin)

using namespace std;
typedef long long ll;
const int maxn = 105;
int n,m;
double val[maxn],d[maxn];
struct Edge
{
    int to;
    double w;
    Edge(int to,double w):to(to),w(w){}
};
vector<Edge>mp[maxn];
struct Node
{
    int u;
    double w;
    Node(int u,double w):u(u),w(w){}
    bool operator<(const Node& rhs)const
    {
        return w<rhs.w;
    }
};

void Dij()
{
    memset(d,0,sizeof(d));
    priority_queue<Node> que;
    d[n] = 1;
    que.push(Node(n,1));
    while(!que.empty())
    {
        Node u = que.top();
        que.pop();
        if(u.w<d[u.u]) continue;
        for(int i=0; i<mp[u.u].size(); i++)
        {
            Edge e = mp[u.u][i];
            if(d[e.to]<d[u.u]*e.w)//走过之后留下的物资如果更大的话
            {
                d[e.to] = d[u.u]*e.w;
                que.push(Node(e.to,d[e.to]));
            }
        }
    }
    return;
}

int main()
{
   // FRE();
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=0; i<maxn; i++) mp[i].clear();
        for(int i=1; i<n; i++)
        {
            scanf("%lf",&val[i]);
        }
        for(int i=0; i<m; i++)
        {
            int u,v;
            double p;
            scanf("%d%d%lf",&u,&v,&p);
            mp[u].push_back(Edge(v,1-p));
            mp[v].push_back(Edge(u,1-p));
        }
        Dij();
        double sum = 0;
        for(int i=1; i<n; i++)
        {
            sum += val[i]*d[i];
        }
        printf("%.2f
",sum);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/sykline/p/10528834.html