codevs 1173 最优贸易

首先为了满足买卖点全都在1到n的路径上,我们进行两次bfs(spfa),在第一次的时候顺便求出1到该点的路径上权值最小的点。

然后o(n)for出该点权值减去1到这一点路径上权值最小的点的权值。更新答案。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define maxv 100005
#define maxe 500005
#define maxn 9999999
using namespace std;
struct edge
{
int v,nxt;
}e1[maxe],e2[maxe];
int g1[maxv],g2[maxv],n,m,w[maxv],x,y,z;
int nume1=0,nume2=0;
int judge[maxv],h[maxv],ans=0;
bool vis[maxv],kk[maxv];
void addedge1(int u,int v)
{
e1[++nume1].v=v;
e1[nume1].nxt=g1[u];
g1[u]=nume1;
}
void addedge2(int u,int v)
{
e2[++nume2].v=v;
e2[nume2].nxt=g2[u];
g2[u]=nume2;
}
void spfa()
{
for (int i=1;i<=n;i++)
h[i]=i;
queue <int> q;
q.push(1);
memset(vis,false,sizeof(vis));
memset(kk,false,sizeof(kk));
kk[1]=true;
while (!q.empty())
{
int head=q.front();
judge[head]=1;
q.pop();
for (int i=g1[head];i;i=e1[i].nxt)
{
int v=e1[i].v;;
if (kk[v]==false)
{
kk[v]=true;
if (w[h[v]]>w[h[head]])
h[v]=h[head];
if (vis[v]==false)
{
vis[v]=true;
q.push(v);
}
}
else if (w[h[v]]>w[h[head]])
{
h[v]=h[head];
if (vis[v]==false)
{
vis[v]=true;
q.push(v);
}
}
}
vis[head]=false;
}
}
void bfs()
{
memset(vis,false,sizeof(vis));
queue <int> q;
q.push(n);
while (!q.empty())
{
int head=q.front();
q.pop();
for (int i=g2[head];i;i=e2[i].nxt)
{
int v=e2[i].v;
if (vis[v]==false)
{
vis[v]=true;
judge[v]++;
q.push(v);
}
}
}
}
int main()
{
memset(g1,0,sizeof(g1));
memset(g2,0,sizeof(g2));
memset(judge,0,sizeof(judge));
memset(h,0,sizeof(h));
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&w[i]);
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
if (z==1)
{
addedge1(x,y);
addedge2(y,x);
}
else
{
addedge1(x,y);
addedge1(y,x);
addedge2(x,y);
addedge2(y,x);
}
}
spfa();
bfs();
for (int i=1;i<=n;i++)
{
if (judge[i]==2)
ans=max(ans,w[i]-w[h[i]]);
}
printf("%d\n",ans);
return 0;
}

你可能感兴趣的:(codevs 1173 最优贸易)