题意:有很多城市的货物需要运送到首都去,但是中途会有运输费用,求可以运送到首都的货物的最大重量。
思路:对首都求一次单源最长路径,使到达首都的货物最多。需要注意两点⑴ 此图有重边。 ⑵有些货物无法送达。
代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int inf = 100000000;
const int maxn = 105;
int n,m;
int city[maxn]; //每个城市要运送的货物
double edge[maxn][maxn]; //城市间的运输费用率
double dist[maxn]; //Dijkstra算法所需的两个数组
bool vis[maxn];
void Input(){
for(int i = 1; i < n; i++)
cin>>city[i];
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++)
edge[i][j] = -inf;
}
int u,v;
double w;
for(int i = 0; i < m; i++){
cin>>u>>v>>w;
if(edge[u][v] < 1.0 - w)
edge[u][v] = edge[v][u] = 1.0 - w;
}
}
void Dijkstra(int s){
for(int i = 1; i <= n; i++){
dist[i] = edge[s][i];
vis[i] = 0;
}
dist[s] = 0; vis[s] = 1;
for(int i = 0; i < n; i++){
double max = -inf;
int v = -1;
for(int j = 1; j <= n; j++){
if(!vis[j] && dist[j] > max){
max = dist[j]; v = j;
}
}
if(v == -1) break;
vis[v] = 1;
for(int j = 1; j <= n; j++){
double value = dist[v] * edge[v][j];
if(!vis[j] && edge[v][j] != -inf && value > dist[j]){
dist[j] = value;
}
}
}
}
void Solve(){
double sum = 0.0;
Dijkstra(n);
for(int i = 1; i < n; i++){
if(dist[i] != -inf)//存在无法到达的情况
sum += dist[i] * city[i];
}
printf("%.2lf\n",sum);
}
int main(){
while(cin>>n>>m){
Input();
Solve();
}
return 0;
}