• P1073 最优贸易


    最优贸易

    洛谷链接

    这道题是09年提高组的第三题。

    题目大意:

    有个商人在一个图上走,图上的点有权值,各个点之间有边相连,求出在商人可以到达终点的条件下,所经历的点的最小权值与最大权值的差(每个点或边可以走多次)。

    这个题有两种做法:

    1.

    用两遍dfs,一遍求出点的min,另一边求出点的max,最后两个数组相减,找出最大值,得出答案。

    代码:

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<iostream>
     5 using namespace std;
     6 int n,m;
     7 int num_edge1,num_edge2;
     8 int ans;
     9 int a[100001];
    10 int    maxx[100001],minn[100001],head1[100001],head2[100001];
    11 int x,y,z;
    12 struct hehe{
    13     int next;
    14     int to;
    15 };
    16 hehe edge1[1000001],edge2[1000001];
    17 inline void add_edge1(int from,int to){
    18     edge1[++num_edge1].next=head1[from];
    19     edge1[num_edge1].to=to;
    20     head1[from]=num_edge1;
    21 }
    22 inline void add_edge2(int from,int to){
    23     edge2[++num_edge2].next=head2[from];
    24     edge2[num_edge2].to=to;
    25     head2[from]=num_edge2;
    26 }
    27 inline void dfs2(int u,int k){
    28     int i,v;
    29     maxx[u]=max(maxx[u],k);
    30     for(i=head2[u];i!=-1;i=edge2[i].next){
    31         v=edge2[i].to;
    32         if(maxx[v]<k)dfs2(v,max(k,a[v]));
    33     }
    34 }
    35 inline void dfs1(int u,int k){
    36     int v;
    37     minn[u]=min(minn[u],k);
    38     for(int i=head1[u];i!=-1;i=edge1[i].next){ 
    39         v=edge1[i].to;
    40         if(minn[v]>k)
    41             dfs1(v,min(k,a[v]));
    42     }
    43 }
    44 int main(){
    45     memset(head1,-1,sizeof(head1));
    46     memset(head2,-1,sizeof(head2));
    47     scanf("%d%d",&n,&m);
    48     for(int i=1;i<=n;i++){
    49         scanf("%d",&a[i]);
    50         maxx[i]=-4200000; 
    51         minn[i]=4200000;
    52     }
    53     for(int i=1;i<=m;i++){
    54         scanf("%d%d%d",&x,&y,&z);
    55         if(z==2){ 
    56             add_edge1(x,y); 
    57             add_edge1(y,x);
    58             add_edge2(x,y);
    59             add_edge2(y,x);
    60         }
    61         else{
    62             add_edge1(x,y);
    63             add_edge2(y,x);
    64         }
    65     }
    66     dfs1(1,a[1]);
    67     dfs2(n,a[n]);
    68     for(int i=1;i<=n;i++)
    69         ans=max(ans,maxx[i]-minn[i]);
    70     printf("%d",ans);
    71     return 0;
    72 }
    View Code

    2.

    先用dfs求出可以到达根节点的节点,之后一遍spfa,求出到该节点时,可以走到的最小的权值是多少,最后找出最大值,得到答案。

    代码:

     1 #include<queue>
     2 #include<cstdio>
     3 #define N 100010
     4 #define M 1000010
     5 using namespace std;
     6 queue<int>p;
     7 int next1[M],to1[M],num1,head1[N];
     8 int next2[M],to2[M],num2,head2[N];
     9 int a,b,c,d[N],dis[N],n,m,u,ans=-1;
    10 bool boo[N],exist[N];
    11 void add1(int false_from,int false_to){
    12     next1[++num1]=head1[false_from];
    13     to1[num1]=false_to;
    14     head1[false_from]=num1;
    15 }
    16 void add2(int false_from,int false_to){
    17     next2[++num2]=head2[false_from];
    18     to2[num2]=false_to;
    19     head2[false_from]=num2;
    20 }
    21 void dfs(int x){
    22     boo[x]=1;
    23     for(int i=head2[x];i;i=next2[i]){
    24         if(!boo[to2[i]])
    25             dfs(to2[i]);
    26     }
    27 }
    28 void spfa(){
    29     for(int i=1;i<=n;++i)
    30         dis[i]=42000000;
    31     p.push(1);
    32     exist[1]=1;
    33     while(!p.empty()){
    34         u=p.front();
    35         p.pop();
    36         exist[u]=0;
    37         for(int i=head1[u];i;i=next1[i])
    38             if(dis[to1[i]]>min(dis[u],d[to1[i]])&&boo[to1[i]]){
    39                 dis[to1[i]]=min(dis[u],d[to1[i]]);
    40                 if(!exist[to1[i]]){
    41                     p.push(to1[i]);
    42                     exist[to1[i]]=1;
    43                 }
    44             }
    45     }
    46 }
    47 int main(){
    48     scanf("%d%d",&n,&m);
    49     for(int i=1;i<=n;++i)
    50         scanf("%d",&d[i]);
    51     for(int i=1;i<=m;++i){
    52         scanf("%d%d%d",&a,&b,&c);
    53         if(c==1){
    54             add1(a,b);
    55             add2(b,a);
    56         }
    57         else{
    58             add1(a,b);
    59             add1(b,a);
    60             add2(b,a);
    61             add2(a,b);
    62         }
    63     }
    64     dfs(n);
    65     spfa();
    66     for(int i=1;i<=n;++i)
    67         ans=max(ans,d[i]-dis[i]);
    68     printf("%d",ans);
    69     return 0;
    70 }
    View Code

    其实个人感觉这两种做法差不多。

  • 相关阅读:
    CSS3选择器之:nth-child(n)
    【转】JS中,中国标准时间转化为yyyy-MM-dd
    【转】浅谈JavaScript中forEach与each
    Can't connect to MySQL server (10060)
    Linux/CentOS下安装MySql RPM Bundle
    查看CentOS/Linux的版本信息
    Java中IO流,输入输出流概述与总结
    阿里历年经典Java面试题汇总
    架构师眼中的高并发架构
    Java面试经
  • 原文地址:https://www.cnblogs.com/jsawz/p/6829077.html
Copyright © 2020-2023  润新知