codevs 1173 最优贸易(DP+SPFA运用)
Posted 一入OI深似海
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs 1173 最优贸易(DP+SPFA运用)相关的知识,希望对你有一定的参考价值。
/* 中国的题目 ——贱买贵卖 0.0 这题wa了好多遍 第一遍看着题 哎呀这不很简单嘛 从起点能到的点都是合法的点 然后统计合法的点里最大最小值 然后printf 也不知道哪里来的自信 就这么交了 然后爆零了 第二遍想了想 恩 刚开始思路有问题 必须先买后卖 买的点要在卖的前面 恩 很有道理 然后数组模拟着统计了一下i之前的最小值和i之后的最大值 并且确保每个点都是合法的 然后 连样例都不对了..... 第三遍 终于找到了问题的关键(好吧我是看到标签里有spfa才想到了) 因为他是图啊 图啊 而且是有向的 而且有双向边 这个嘛 当然还是跑一遍这个图 按照跑的顺序更新最大最小值 所以正反建边 正反分别跑最大最小就ok了 下面是wa的代码 */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 500010 using namespace std; int n,m,num,head[maxn],v[maxn],sm[maxn],bi[maxn]; bool f[maxn]; struct node { int v,pre; }e[maxn*2]; int init() { int x=0;char s=getchar(); while(s<‘0‘||s>‘9‘)s=getchar(); while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();} return x; } void Add(int from,int to) { num++; e[num].v=to; e[num].pre=head[from]; head[from]=num; } void Dfs(int s) { for(int i=head[s];i;i=e[i].pre) if(f[e[i].v]==0) { f[e[i].v]=1; Dfs(e[i].v); } } void Get_sb() { sm[0]=maxn; for(int i=1;i<=n;i++)sm[i]=min(v[i],sm[i-1]); for(int i=n;i>=1;i--)bi[i]=max(v[i],bi[i-1]); } int main() { n=init();m=init(); for(int i=1;i<=n;i++) v[i]=init(); int x,y,z; for(int i=1;i<=m;i++) { x=init();y=init();z=init(); if(z==1)Add(x,y); else Add(x,y),Add(y,x); } f[1]=1;Dfs(1); Get_sb(); int minn=0x3f3f3f3f,maxx=0; for(int i=1;i<=n;i++) if(f[i]) { minn=min(minn,bi[i]-sm[i]); maxx=max(maxx,bi[i]-sm[i]); } printf("%d\n",maxx-minn); return 0; }
/*这是Ac的代码*/ #include<iostream> #include<cstdio> #include<cstring> #include<queue> #define maxn 500010 using namespace std; int n,m,num,num2,head[maxn],head2[maxn],v[maxn],dx[maxn],dy[maxn],ans; bool f[maxn]; struct node { int v,pre; }e[maxn*2],e2[maxn*2]; int init() { int x=0;char s=getchar(); while(s<‘0‘||s>‘9‘)s=getchar(); while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();} return x; } void Add(int from,int to) { num++; e[num].v=to; e[num].pre=head[from]; head[from]=num; } void Add2(int from,int to) { num2++; e2[num2].v=to; e2[num2].pre=head2[from]; head2[from]=num2; } void SPFA(int s) { memset(dx,127/3,sizeof(dx)); f[s]=1;dx[s]=v[s]; queue<int>q; q.push(s); while(!q.empty()) { int k=q.front();q.pop(); for(int i=head[k];i;i=e[i].pre) { dx[e[i].v]=min(dx[e[i].v],min(v[e[i].v],dx[k])); if(f[e[i].v]==0) { f[e[i].v]=1; q.push(e[i].v); } } } } void SPFA2(int s) { f[s]=1;dy[s]=v[s]; queue<int>q; q.push(s); while(!q.empty()) { int k=q.front();q.pop(); for(int i=head2[k];i;i=e2[i].pre) { dy[e2[i].v]=max(dy[e2[i].v],max(v[e2[i].v],dy[k])); if(f[e2[i].v]==0) { f[e2[i].v]=1; q.push(e2[i].v); } } } } int main() { n=init();m=init(); for(int i=1;i<=n;i++) v[i]=init(); int x,y,z; for(int i=1;i<=m;i++) { x=init();y=init();z=init(); if(z==1)Add(x,y),Add2(y,x); else Add(x,y),Add(y,x),Add2(x,y),Add2(y,x); } SPFA(1);memset(f,0,sizeof(f));SPFA2(n); int minn=0x3f3f3f3f,maxx=0; for(int i=1;i<=n;i++) ans=max(ans,dy[i]-dx[i]); printf("%d\n",ans); return 0; }
以上是关于codevs 1173 最优贸易(DP+SPFA运用)的主要内容,如果未能解决你的问题,请参考以下文章
NOIP2009最优贸易[spfa变形|tarjan 缩点 DP]