• hdu 6201 transaction transaction transaction


    题意:一棵树,有点权,边权,问选择2个点,即abs(a[i]-a[j]) - (这两点经过的边权) 最大

    思路: 我们假设买为 x ,卖为y ,路径消耗为z  ,即 x- (y+z)最大,即-(x-(y+z))最小,

        我们增加一个0点,他到每个点的距离为- 该点权值 (即买书的钱

        增加个n+1点,到每个点的距离为该点权值(即卖书的到的钱

        0到n+1跑个最短路即可

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=3e6+10;;
     4 const int INF=1000000;
     5 int n,m,dis[N],head[N],len;
     6 bool vis[N];
     7 int b[N];
     8 
     9 struct edge
    10 {
    11     int to,val,next;
    12 }e[N];
    13 
    14 void add(int from,int to,int  val)
    15 {
    16     e[len].to=to;
    17     e[len].val=val;
    18     e[len].next=head[from];
    19     head[from]=len++;
    20 }
    21 struct point
    22 {
    23     int val,id;
    24     point(int id,int val):id(id),val(val){}
    25     bool operator <(const point &x)const{
    26         return val>x.val;
    27     }
    28 };
    29 void dijkstra(int s)
    30 {
    31     memset(vis,0,sizeof(vis));
    32     for(int i=0;i<N;i++)
    33         dis[i]=INF;
    34     priority_queue<point> q;
    35     q.push(point(s,0));
    36     dis[s]=0;
    37     while(!q.empty())
    38     {
    39         int cur=q.top().id;
    40         q.pop();
    41         if(vis[cur]) continue;
    42         vis[cur]=true;
    43         for(int i=head[cur];i!=-1;i=e[i].next)
    44         {
    45             int id=e[i].to;
    46             if(!vis[id] && dis[cur]+e[i].val < dis[id])
    47             {
    48                 dis[id]=dis[cur]+e[i].val;
    49                 q.push(point(id,dis[id]));
    50             }
    51         }
    52     }
    53 }
    54 
    55 int main()
    56 {
    57     int t;
    58     cin>>t;
    59     while(t--)
    60     {
    61         scanf("%d",&n);
    62         len=0;
    63         for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    64         memset(head,-1,sizeof(head));
    65         for(int i=1;i<n;i++)
    66         {
    67             int from,to,val;
    68             scanf("%d%d%d",&from,&to,&val);
    69             add(from,to,val);
    70             add(to,from,val);
    71         }
    72         for(int i=1;i<=n;i++){
    73             add(0,i,-b[i]);
    74             add(i,0,-b[i]);
    75         }
    76         for(int i=1;i<=n;i++){
    77             add(n+1,i,b[i]);
    78             add(i,n+1,b[i]);
    79         }
    80         dijkstra(0);
    81         printf("%d
    ",abs(dis[n+1]));
    82     }
    83     return 0;
    84 
    85 }
  • 相关阅读:
    C#实现一个万物皆可排序的队列
    面试官:Redis 过期删除策略和内存淘汰策略有什么区别?
    递归基础练习1
    异步调用
    归并排序
    常见排序算法整理(冒泡、选择、插入、堆等)
    最大堆和最小堆java代码实现
    web内容如何保护:如何有效地保护 HTML5 格式的视频内容?
    TML转义字符:xss攻击与HTML字符的转义和反转义
    新一代构建工具(1):对比rollup/parcel/esbuild—esbuild脱颖而出
  • 原文地址:https://www.cnblogs.com/hhxj/p/7505239.html
Copyright © 2020-2023  润新知