NOIP2009提高組Day?T3
阿新 • • 發佈:2018-12-19
Analysis
兩遍SPFA 1.求出1~i的路徑上點權最小值 2.求出i~n的路徑上點權最大值 最後列舉每一個點作為出售點,得到答案
喵喵喵,太妙了!!! 這道題結合了反向建圖+SPFA最短路思想 看了題解發現很簡單,但自己就是沒想到 只能亂搞拿到20分,菜啊……
剛看了題解的時候,以為可以用Topsort來代替SPFA 但仔細想了一下,Topsort一遇到雙向邊,相當於遇到了環,就咕咕了 還是SPFA好
Summary
注意初始值 今天因為初值太大爆int,貢獻了好幾發WA 這一定是老天在提醒我NOIP正式考試的時候 一定要注意初始值相加減會不會爆int!!Orz感謝
Code
#include<bits/stdc++.h>
#define in read()
#define N 100009
#define M 1000009
#define inf 105
using namespace std;
inline int read(){
char ch;int f=1,res=0;
while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1;
while(ch>='0'&&ch<='9'){
res=(res<<1)+(res<< 3)+ch-'0';
ch=getchar();
}
return f==1?res:-res;
}
bool vis[N];
int n,m,val[N],mn[N],mx[N];
int nxt[M],to[M],head[N],ecnt=0;
inline void add(int x,int y){nxt[++ecnt]=head[x];head[x]=ecnt;to[ecnt]=y;}
int Nxt[M],To[M],Head[N],Ecnt=0;
inline void readd(int x,int y){Nxt[++Ecnt]=Head[x];Head[ x]=Ecnt;To[Ecnt]=y;}
inline void spfa1(){
queue<int> q;q.push(1);mn[1]=val[1];
while(!q.empty()){
int u=q.front();q.pop();vis[u]=0;
for(int e=head[u];e;e=nxt[e]){
int v=to[e];
int tmp=min(mn[u],val[v]);
if(mn[v]>tmp) {
mn[v]=tmp;
if(!vis[v]) q.push(v),vis[v]=1;
}
}
}
}
inline void spfa2(){
queue<int> q;q.push(n);mx[n]=val[n];
while(!q.empty()){
int u=q.front();q.pop();vis[u]=0;
for(int e=Head[u];e;e=Nxt[e]){
int v=To[e];
int tmp=max(mx[u],val[v]);
if(mx[v]<tmp) {
mx[v]=tmp;
if(!vis[v]) q.push(v),vis[v]=1;
}
}
}
}
int main(){
n=in;m=in;
int i,j,k,x,y,z;
for(i=1;i<=n;++i) {
val[i]=in;
mx[i]=-inf;mn[i]=inf;
}
for(i=1;i<=m;++i){
x=in;y=in;z=in;
add(x,y);readd(y,x);
if(z==2){add(y,x);readd(x,y);}
}
spfa1();//求出1~i的路徑上點權最小值
spfa2();//求出i~n的路徑上點權最大值
int ans=0;
for(i=1;i<=n;++i)
ans=max(ans,mx[i]-mn[i]);
cout<<ans;
return 0;
}