HDU 6201 transaction transaction transaction(最短路)

来源:互联网 发布:开淘宝网店花钱吗 编辑:程序博客网 时间:2024/06/11 20:20

解法:由于每个点有一个商品,花费为w,我们想卖出去,但是路也有花费,如果在某个点卖出去,相当于赚回wi元。那么我们建图,一个起点向每个点连接一个边权为-wi的边,每个点向终点连接一个边权为+wi的边,原图中的边也加进去,从起点向终点跑一边spfa即可。

代码如下:

#include<iostream>#include<cstdio>#include<vector>#include<queue>#include<utility>#include<stack>#include<algorithm>#include<cstring>#include<string>#include<cmath>#include<set>#include<map>using namespace std;typedef pair<int, int> pii;const int maxn = 1e5 + 5;const int INF = 0x7fffffff;int n;int a[maxn];vector <pii> edge[maxn];int dis[maxn];bool flag[maxn];void spfa(int s, int t) {fill(dis, dis + t + 1, -INF);dis[s] = 0;memset(flag, 0, sizeof(flag));queue <int> q;q.push(s);while(!q.empty()) {int u = q.front();q.pop();flag[u] = 0;for(int i = 0; i < edge[u].size(); i++) {int v = edge[u][i].second;int d = edge[u][i].first + dis[u];if(dis[v] < d) {dis[v] = d;if(!flag[v]) {flag[v] = 1;q.push(v);}}}}}int main() {#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);#endifint T;scanf("%d", &T);while(T--) {scanf("%d", &n);for(int i = 1; i <= n; i++)scanf("%d", &a[i]);for(int i = 1, u, v, val; i < n; i++) {scanf("%d%d%d", &u, &v, &val);edge[u].push_back(pii(-val, v));edge[v].push_back(pii(-val, u));}for(int i = 1; i <= n; i++) {edge[0].push_back(pii(-a[i], i));edge[i].push_back(pii(a[i], n + 1));}spfa(0, n + 1);printf("%d\n", dis[n + 1]);for(int i = 0; i <= n + 1; i++)edge[i].clear();}return 0;}


原创粉丝点击