noip2009最优贸易——spfa

Posted on 2018-05-05 18:09  15ozwly1  阅读(87)  评论(0编辑  收藏  举报

题目描述:有一张图,共有n个节点,m条边,保证节点1到节点n有通路,找到一条路径上的两个节点(记为p,q——在该路径中,p在q之前),使p与q的权值之差最大;

 

蒟蒻思路:spfa求(p与q)的差值最大

        在spfa的过程中,记每个队首元素为x,与其相连的节点记为y,则对于每个节点y,它的最优解(差值最大)只可能被两个量更新:

      1.x的最优解;

      2.节点y的权值-节点x的权值

辣鸡代码献上:

#include<bits/stdc++.h>
using namespace std;
struct Node{
    int to,next;
}e[2000005];

int pr[100005],cnt;
int n,m;
int head[500005],d[100005];
bool v[100005];

queue<int> q;


void addedge(int x,int y)
{
    e[++cnt].to=y;
    e[cnt].next=head[x];
    head[x]=cnt;
}

void spfa()
{ 
    memset(d,-1,sizeof(d));
    q.push(1);
    v[1]=true;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        v[x]=false;
        for(int i=head[x];i;i=e[i].next)
        {
            int u=e[i].to,f=1;
            if(d[u]==-1||d[u]<pr[u]-pr[x])
            {
                if(pr[u]-pr[x]>0)d[u]=pr[u]-pr[x];
                f=0;
            }
            if(d[u]<d[x])
            {
                d[u]=d[x];
                f=0;
            }    
            if(!f)
            {
                q.push(u);
                v[u]=true;
            }
        }
    }
}

int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%d",&pr[i]);
    for(int i=1;i<=m;i++)
    {
        int x,y,q;
        scanf("%d %d %d",&x,&y,&q);
        addedge(x,y);
        if(q==2)addedge(y,x);
    }
    spfa();
    if(d[n]==-1)printf("0");
    else        printf("%d\n",d[n]);
    return 0;
}