http://acm.hdu.edu.cn/showproblem.php?pid=6201
给定一个图,和某个点书的价格,你可以从某一点买书 在另一点卖,赚一个差价,但是旅途也是要钱的。问你最多赚多少钱。
dfs。
#include<bits/stdc++.h>
using namespace std;
/* 先求以x为开始点的距离。
但是这样没有考虑子节点。在考虑一下子节点
树的直径也是这么求得。。
*/
const int maxn=2e5+1000;
struct Node{
int to,next,cost;
}node[maxn];
int len;
int head[maxn];
void add(int a,int b,int c){
node[len].to=b;
node[len].cost=c;
node[len].next=head[a];
head[a]=len++;
}
int cost[maxn];
int val[maxn];
int vis[maxn];
void dfs1(int u){
cost[u]=val[u];
vis[u]=true;
//cout<<u<<" "<<pre<<endl;
for(int i=head[u];i!=-1;i=node[i].next){
int to=node[i].to;
int ccc=node[i].cost;
//cout<<to<<" "<<u<<endl;
if(!vis[to]){
dfs1(to);
cost[u]=min(cost[to]+ccc,cost[u]);
}
}
}
void dfs2(int u){
//cout<<u<<"!!"<<pre<<endl;
vis[u]=true;
for(int i=head[u];i!=-1;i=node[i].next){
int to=node[i].to;
int ccc=node[i].cost;
if(!vis[to]) {
cost[to]=min(cost[to],cost[u]+ccc);
dfs2(to);
}
}
}
void init(){
len=0;
memset(head,-1,sizeof(head));
}
int main()
{ int t,m,a,b,c;
scanf("%d",&t);
while(t--){
init();
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d",&val[i]);
for(int i=1;i<=m-1;i++){
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
//cout<<a<<" "<<b<<" "<<c<<endl;
}
memset(vis,false,sizeof(vis));
dfs1(1);
memset(vis,false,sizeof(vis));
dfs2(1);
int all=-1;
for(int i=1;i<=m;i++){
all=max(all,val[i]-cost[i]);
}
printf("%d\n",all);
}
return 0;
}
或者 见图拆点 跑一次最长路(也有跑网络流的。)
#include <bits/stdc++.h>
using namespace std;
/* 或者建一个图,求最长路。。
有直接spfa的,有用网络流求得。。
*/
typedef long long ll;
const int maxn=6e5+1000;
struct Node{
int to,next;ll cost;
}node[maxn];
int len,m;
int head[maxn];
void add(int a,int b,ll c){
node[len].to=b;
node[len].cost=c;
node[len].next=head[a];
head[a]=len++;
}
long long d[maxn];
bool vis[maxn];
ll val[maxn];
void spfa(int s){
queue<int>q;
memset(vis,false,sizeof(vis));
for(int i=0;i<=2*m+1;i++){
d[i]=-1e15;
}
q.push(s);
d[s]=0;
vis[s]=true;
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i!=-1;i=node[i].next){
int to=node[i].to;
int ccc=node[i].cost;
if(d[to]<d[u]+ccc){
d[to]=d[u]+ccc;
if(!vis[to]){
vis[to]=true;
q.push(to);
}
}
}
}
}
void init(){
len=0;
memset(head,-1,sizeof(head));
}
int main()
{ int t,a,b;
ll c;
scanf("%d",&t);
while(t--){
scanf("%d",&m);
init();
for(int i=1;i<=m;i++){
scanf("%lld",&val[i]);
add(i,i+m,0);
add(0,i,-val[i]);
}
for(int i=1;i<m;i++){
scanf("%d%d%lld",&a,&b,&c);
add(a+m,b,-c);
add(b+m,a,-c);
}
for(int i=1;i<=m;i++){
add(i+m,2*m+1,val[i]);
}
spfa(0);
printf("%lld\n",d[2*m+1]);
}
return 0;
}