zoukankan      html  css  js  c++  java
  • 洛谷 P1073 最优贸易

    题目传送门

    解题思路:

    先吐槽一下,因为本人太弱,狂肝4.5小时才A掉.要是在考场上不就废了

    本题拿过来,很明显的贪心思路就是在每条1到n的路径上找最大和最小值,然后做差维护答案.

    然而这样是不对,因为有可能对于一条路径,最小值在最大值后面出现,而这样这条路径上的答案明显不是它们的差值.

    怎么办呢? 答案就是我们可以对于每个点,注意是每个"点",找1到这个点路径上的最小值,这个点到n的最大值,作差,这样至少对于这个点来说是最优解.

    然后对于所有在1到n路径上的点的差维护最大值即可.

    还有一个问题,我们怎样知道哪些点能从1到这个点然后再走到n呢?

    当然从1走到当前点好办,直接遍历即可.那n呢,怎么办?其实只要反过来一想,把n想象成1,倒着便利一遍这个图就行.

    所以,综上所述,只要正着跑一遍SPFA,反着跑一遍SPFA,然后维护答案即可.

    注意:

    1.因为要跑两遍SPFA,所以我们要正着,反着存两遍图

    2.正着的SPFA是求最小值,而反着的SPFA是求最大值.

    AC代码:

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<queue>
      5 #include<algorithm>
      6 #include<limits.h>
      7 
      8 using namespace std;
      9 
     10 queue<int > l1,l2;
     11 int a1,bn,n,m,a[100001],head[100001],tot,head1[100001],_tot,dist[100001],b[100001],dist1[100001]; 
     12 bool p[100001];
     13 struct kkk {
     14     int next,to,v;
     15 }e[500001],e1[500001];
     16 
     17 inline void add(int x,int y) {
     18     e[++tot].to = y;
     19     e[tot].next = head[x];
     20     e[tot].v = a[y];
     21     head[x] = tot;
     22 }
     23 
     24 inline void add1(int x,int y) {
     25     e1[++_tot].to = y;
     26     e1[_tot].next = head1[x];
     27     e1[tot].v = b[y];
     28     head1[x] = _tot;
     29 }
     30 
     31 inline void spfa_first_time(int s) {
     32     memset(dist,0x3f,sizeof(dist));
     33     memset(p,0,sizeof(p));
     34     dist[s] = a[s];
     35     l1.push(s);
     36     p[s] = true;
     37     while(!l1.empty()) {
     38         int u = l1.front();
     39         l1.pop();
     40         p[u] = false;
     41         for(int i = head[u];i != -1; i = e[i].next) {
     42             int end = e[i].to;
     43             int len = e[i].v;
     44             if(dist[u] < dist[end] || len < dist[end]) {
     45                 dist[end] = min(dist[u],len);
     46                 if(!p[end]) {
     47                     l1.push(end);
     48                     p[end] = 1;
     49                 }
     50             }    
     51         }
     52     }
     53 }
     54 
     55 inline void spfa_last_time(int s) {
     56     memset(dist1,0x80,sizeof(dist1));
     57     memset(p,0,sizeof(p));
     58     dist1[s] = b[s];
     59     l2.push(s);
     60     p[s] = true;
     61     while(!l2.empty()) {
     62         int u = l2.front();
     63         l2.pop();
     64         p[u] = false;
     65         for(int i = head1[u];i != -1; i = e1[i].next) {
     66             int end = e1[i].to;
     67                int len = e1[i].v;
     68             if(dist1[u] > dist1[end] || len > dist1[end]) {
     69                 dist1[end] = max(dist1[u],len);
     70             if(!p[end]) {
     71                 l2.push(end);
     72                 p[end] = 1;
     73             }}
     74         }
     75     }
     76 }
     77 
     78 bool cmp(int q,int r) {
     79     return q > r;
     80 }
     81 
     82 int main() {
     83     memset(head,-1,sizeof(head));
     84     memset(head1,-1,sizeof(head1));
     85     scanf("%d%d",&n,&m);
     86     for(int i = 1;i <= n; i++) {
     87         scanf("%d",&a[i]);
     88         b[i] = a[i];
     89     }
     90     for(int i = 1;i <= m; i++) {
     91         int x,y,z;
     92         scanf("%d%d%d",&x,&y,&z);
     93         if(z == 1) {
     94             add(x,y);
     95             add1(y,x);
     96         }
     97         if(z == 2) {
     98             add(x,y);
     99             add(y,x);
    100             add1(x,y);
    101             add1(y,x);
    102         }
    103     }
    104     spfa_first_time(1);//正着 
    105     spfa_last_time(n);//反着 
    106     for(int i = 1;i <= n; i++) 
    107         a[i] = dist1[i] - dist[i];
    108     sort(a+1,a+1+n,cmp);
    109     if(a[1] <= 0 || a[1] >= 0x3f3f3f3f) printf("0");
    110     else printf("%d",a[1]);
    111     return 0;
    112 }

    //NOIP2009提高 T3

  • 相关阅读:
    js如何识别后端返回的“↵”,让其换行
    ReactNative插件
    ReactNative踩坑
    js对当前时间进行处理
    vue-awesome-swiper手动滑动后不再自动轮播的问题
    HTML5知识点汇总
    懒加载的实现原理及一些实现方法
    使用node.js实现多人聊天室(socket.io、B/S)
    [vue学习] 卡片展示分行功能简单实现
    [vue学习]快速搭建一个项目
  • 原文地址:https://www.cnblogs.com/lipeiyi520/p/11306185.html
Copyright © 2011-2022 走看看