您的位置:首页 > 其它

[NOIP 2009]最优贸易 Spfa

2015-11-04 12:00 190 查看

题目大意

求一条路上最大的点值之差。

正反两边spfa;orz tarjin缩点神犇

代码

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;

struct Holder{
int to,next;
}e1[500005],e2[500005];

int head1[100005],head2[100005],vis1[100005],vis2[100005],imin[100005],imax[100005];
int n,m,cost[100005],ans=0;

int cnt1=1;
void Add1(int u,int v){
e1[cnt1].to=v;
e1[cnt1].next=head1[u];
head1[u]=cnt1++;
}

int cnt2=1;
void Add2(int u,int v){
e2[cnt2].to=v;
e2[cnt2].next=head2[u];
head2[u]=cnt2++;
}

int Spfa1(){
queue<int> Q;
Q.push(1);vis1[1]=1;imin[1]=cost[1];
while(!Q.empty()){
int now=Q.front();Q.pop();vis1[now]=1;
for(int i=head1[now];i;i=e1[i].next){
int v=e1[i].to;
imin[v]=min(cost[v],imin[now]);
if(!vis1[v]){
Q.push(v);

}
}
}
}

int Spfa2(){
queue<int> Q;
Q.push(n);vis2
=1;imax
=cost
;
while(!Q.empty()){
int now=Q.front();Q.pop();vis2[now]=1;
for(int i=head2[now];i;i=e2[i].next){
int v=e2[i].to;
imax[v]=max(imax[now],cost[v]);
if(!vis2[v]){
Q.push(v);
}
}
}
}
void Initialize(){
memset(vis1,0,sizeof(vis1));
memset(vis2,0,sizeof(vis2));
memset(head1,0,sizeof(head1));
memset(head2,0,sizeof(head2));
memset(imin,127,sizeof(imin));
memset(imax,0,sizeof(imax));
}

int main(){
Initialize();
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%d",&cost[i]);
}
for(int i=1;i<=m;i++){
int u,v,z;
scanf("%d%d%d",&u,&v,&z);
if(z==2){
Add1(u,v);
Add1(v,u);
Add2(u,v);
Add2(v,u);
}else if(z==1){
Add1(u,v);
Add2(v,u);
}
}
Spfa1();
Spfa2();
for(int i=1;i<=n;i++){
ans=max(ans,imax[i]-imin[i]);
}
cout<<ans<<endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: