Title Link: http://acm.hdu.edu.cn/showproblem.php?pid=6201
There is a price for goods in each place. You can buy and sell them in any two places. There is also a toll between the two places. Seek the maximum profit finally obtained.
Idea: the topic requires the maximum profit. We set up a super source point and super exchange point. From the super source point to each point, we spend - val to buy things, and from each point to the super exchange point, we earn val from selling things. Then, the edge with negative weight is established to represent the road cost, and then the longest spfa road or the cost flow can be run once.
spfa:
#include <bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define GT() int T;scanf("%d",&T);while(T--) const int maxn = 1e5+7; int n,m; int d[maxn], vis[maxn], v[maxn]; int s, t; vector<pair<int,int> >E[maxn]; void init() { memset(vis,0,sizeof(vis)); for(int i = 0; i <= n + 1; i++) E[i].clear(), d[i] = -inf; } void spfa() { queue <int> Q; Q.push(s); while(!Q.empty()) { int now = Q.front(); Q.pop(); vis[now] = 0; for(int j = 0; j < E[now].size(); j++) { int v = E[now][j].first; if(d[v] < d[now] + E[now][j].second) { d[v] = d[now] + E[now][j].second; if(vis[v]) continue; vis[v] = 1; Q.push(v); } } } } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d", &n); init(); for(int i = 1; i <= n; i++) scanf("%d", &v[i]); int a, b, x; for(int i = 0; i < n-1; i++) { scanf("%d%d%d",&a, &b, &x); E[a].push_back({b, -x}); E[b].push_back({a, -x}); } s = 0, t = n + 1; for(int i = 1; i <= n; i++) { E[s].push_back({i, -v[i]}); E[i].push_back({t, v[i]}); } d[s] = 0; vis[s] = 1; spfa(); printf("%d\n",d[t]); } return 0; } /* 1 4 10 40 15 30 1 2 30 1 3 2 3 4 10 */
Cost flow:
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e6 + 7; bool vis[maxn]; int n,m,x,y,z,f,dis[maxn],pre[maxn],last[maxn],flow[maxn],maxflow,mincost; struct node{int next,to,flow,dis;}edge[maxn]; int head[maxn],cnt; queue <int> q; void add(int u,int v,int flow,int dis) { edge[cnt] = (node){head[u],v,flow,dis}; head[u] = cnt++; edge[cnt] = (node){head[v],u,0,-dis}; head[v] = cnt++; } bool spfa(int s,int t) { for(int i = 0; i < t + 10; i++) dis[i] = inf, flow[i] = inf, vis[i] = 0; q.push(s); vis[s] = 1; dis[s] = 0; pre[t] = -1; while (!q.empty()) { int now = q.front(); q.pop(); vis[now] = 0; for (int i = head[now]; i != -1; i = edge[i].next) { if (edge[i].flow > 0 && dis[edge[i].to] > dis[now] + edge[i].dis) { dis[edge[i].to] = dis[now] + edge[i].dis; pre[edge[i].to] = now; last[edge[i].to] = i; flow[edge[i].to] = min(flow[now],edge[i].flow); if (!vis[edge[i].to]) { vis[edge[i].to] = 1; q.push(edge[i].to); } } } } return pre[t] != -1; } void MCMF(int s, int t) { maxflow = 0, mincost = 0; while(spfa(s,t)) { int now = t; maxflow += flow[t]; mincost += flow[t]*dis[t]; while (now != s) { edge[last[now]].flow -= flow[t]; edge[last[now]^1].flow += flow[t]; now = pre[now]; } } } int main() { int T; scanf("%d",&T); while(T--) { memset(head,-1,sizeof(head)); cnt = 0; scanf("%d",&n); int s = 0; int s1 = n + 1; int t = n + 2; add(s, s1, 1, 0); for(int i = 1; i <= n; i++) { int val; scanf("%d",&val); add(s1,i,1,-val); add(i,t,1,val); } for(int i = 1; i <= n - 1; i++) { scanf("%d%d%d",&x,&y,&f); add(x,y,1,f); add(y,x,1,f); } MCMF(s, t); printf("%d\n",abs(mincost)); } return 0; } /* 1 4 10 40 15 30 1 2 30 1 3 2 3 4 10 */