题目:
有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; }