NOIP2009提高组Day?T3 - 最优贸易

传送门


Analysis

两遍SPFA
1.求出1~i的路径上点权最小值 m n [ i ] mn[i] mn[i]
2.求出i~n的路径上点权最大值 m x [ i ] mx[i] mx[i]
最后枚举每一个点作为出售点, m x [ i ] − m n [ i ] mx[i]-mn[i] mx[i]mn[i]得到答案

喵喵喵,太妙了!!!
这道题结合了反向建图+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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值