zoukankan      html  css  js  c++  java
  • NOIP2009 最优贸易(BFS)

    本题正解是tarjan。我没有去写

    之前的代码是错误的不好意思,因为数据太弱一直没有发现。

    相同还是两遍bfs,一次正向,一次反向。在正向的时候我们求出从起点走到各个点的最小值。在反向的时候求出从终点走向起点的最大值。

    这样一来,便能够知道对于每个点i。在1到n的路径上面,经过的最大值是多少。经过的最小值是多少。最后max(mx[i]-mp[i])就是要求的答案。

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<cstring>
    #define MAXN 100005
    using namespace std;
    struct T
    {
        int v;
        int next;
    }edge[500005],edge2[500005];
    int cnt,cnt2;
    int head[MAXN],head2[MAXN];
    void add_edge(int u,int v)
    {
        edge[cnt].v = v;
        edge[cnt].next = head[u];
        head[u] = cnt++;
    }
    void add_edge2(int u,int v)
    {
        edge2[cnt2].v = v;
        edge2[cnt2].next = head2[u];
        head2[u] = cnt2++;
    }
    int mx[MAXN],mp[MAXN],w[MAXN];
    bool able[MAXN],vis[MAXN];
    int n,m;
    void bfs1()
    {
    	memset(mp,0x3f,sizeof mp);
    	queue<int> myque;
    	myque.push(1);
    	vis[1] = 1;
        while(!myque.empty())
        {
            int u  = myque.front();
            vis[u] = 0;
            myque.pop();
    		mp[u] = min(mp[u],w[u]);
            for(int i = head[u]; i != -1; i = edge[i].next)
            {
                int v = edge[i].v;
                if(mp[v]  > mp[u])
                {
                    mp[v] = mp[u];
                    if(!vis[v])
                    {
                        vis[v] = 1;
                        myque.push(v);
                    }
                }
            }
        }
    }
    void bfs2()
    {
    	memset(mx,0,sizeof mx);
    	queue<int> myque;
        myque.push(n);
        able[n] = 1;
        while(!myque.empty())
        {
            int u  = myque.front();
            able[u] = 0;
            myque.pop();
    		mx[u] = max(mx[u],w[u]);
            for(int i = head2[u]; i != -1; i = edge2[i].next)
            {
                int v = edge2[i].v;
                if(mx[v]  < mx[u])
                {
                    mx[v] = mx[u];
                    if(!able[v])
                    {
                        able[v] = 1;
                        myque.push(v);
                    }
                }
            }
        }
    }
    int main()
    {
        memset(head,-1,sizeof head);
        memset(head2,-1,sizeof head2);
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= n; i++)
            scanf("%d",&w[i]);
        for(int i = 1; i <= m; i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add_edge(x,y);
            add_edge2(y,x);
            if(z == 2)
            {
                add_edge(y,x);
                add_edge2(x,y);
            }
        }
        bfs2();//反向,找n到i路径上的最大值
        bfs1();//正向,找1到i路径上的最小值
        int ans = 0;
        for(int i = 1; i <= n; i++)
    		ans = max(ans,mx[i]-mp[i]);
        printf("%d
    ",ans);
        return 0;
    }
    /*4 3 
    10 10 1 10
    1 2 1
    2 4 1
    3 2 1 */



  • 相关阅读:
    最长公共子序列算法问题代码(使用JavaScript实现)
    硬币找零问题算法几种不同的代码实现方式(使用Python实现)
    基数排序(使用Python实现)
    桶排序(使用Python实现)
    减法要用 signed 型
    16系列和18系列的不同
    Proteus中常用元器件名字
    数值类型
    PIC单片机之时钟设置
    MOS管使PIC单片机不能正常运行
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/7028039.html
Copyright © 2011-2022 走看看