码迷,mamicode.com
首页 > 其他好文 > 详细

NOIP2009 最优贸易(BFS)

时间:2015-08-10 22:07:30      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:bfs   图论   

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

用两次BFS,第一次BFS在原图的反图上做,从n开始,找到从n出发能够达到到达的所有点。

第二次BFS从起点开始,保存每个点到n点路径上面的最小值mp[i]。

最后遍历一遍,求出w[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 mp[MAXN],w[MAXN];
bool able[MAXN],vis[MAXN];
queue<int> myque;
int n,m;
void bfs1()
{
    for(int i = 1; i <= n; i++)//vis[i]表示i是否在队列中,这样写可以避免图中环造成的影响
    {
        myque.push(i);
        vis[i] = 1;
    }
    while(!myque.empty())
    {
        int u  = myque.front();
        vis[u] = 0;
        myque.pop();
        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()
{
    myque.push(n);
    able[n] = 1;
    while(!myque.empty())
    {
        int u = myque.front();
        myque.pop();
        for(int i = head2[u]; i != -1; i = edge2[i].next)
        {
            int v = edge2[i].v;
            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]);
        mp[i] = 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();//反向,找能到达的点
    bfs1();//正向,找i到n路径上最大值
    int ans = 0;
    for(int i = 1; i <= n; i++)
        if(able[i])
            ans = max(ans,w[i]-mp[i]);
    printf("%d\n",ans);
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

NOIP2009 最优贸易(BFS)

标签:bfs   图论   

原文地址:http://blog.csdn.net/cqbzwja/article/details/47405497

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!