Vijos1754 最优贸易

来源:互联网 发布:遗传算法工具箱怎么用 编辑:程序博客网 时间:2024/05/16 13:54
  • 题目大意:给定一张有向图,求从起点到终点最大值与最小值的差值(这么说还不准确,下文有解释)的最大值。

  • 思路:可以tarjan+DP,不过SPFA是可以解决的。由于只能先买入再卖出,因此要先正向spfa求出到某一点时可能的最小值,再反向spfa求出到某一点时可能的最大值,同时记录点的访问情况,这样两次都被访问过的点就在起点到终点的路径上。最后扫描这些点即可。

  • 代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>using namespace std;const int maxn=100005;int n,m,a[maxn],ma[maxn],mi[maxn];vector<int> g[maxn],rg[maxn];bool can[maxn],rcan[maxn];void init(){     scanf("%d%d",&n,&m);     for (int i=1;i<=n;++i)       scanf("%d",&a[i]);     for (int i=1;i<=m;++i)     {         int a,b,c;         scanf("%d%d%d",&a,&b,&c);         if (c==1)         {             g[a].push_back(b);             rg[b].push_back(a);         }         else         {             g[a].push_back(b);             rg[b].push_back(a);             g[b].push_back(a);             rg[a].push_back(b);         }     }}queue<int> q;bool vis[maxn];void rspfa(int s){     memset(vis,0,sizeof(vis));     memset(ma,0,sizeof(ma));     memset(rcan,0,sizeof(rcan));     vis[s]=1;     rcan[s]=1;     ma[s]=a[s];     q.push(s);     while (!q.empty())     {           int h=q.front();           q.pop();           vis[h]=0;           for (int i=0;i<rg[h].size();++i)           {               if (ma[rg[h][i]]<max(ma[h],a[rg[h][i]]))               {                   ma[rg[h][i]]=max(ma[h],a[rg[h][i]]);                   if (!rcan[rg[h][i]])                     rcan[rg[h][i]]=1;                   if (!vis[rg[h][i]])                   {                       vis[rg[h][i]]=1;                       q.push(rg[h][i]);                   }               }           }     }}void spfa(int s){     memset(vis,0,sizeof(vis));     memset(mi,0x3f3f3f,sizeof(mi));     memset(can,0,sizeof(can));     vis[s]=1;     mi[s]=a[s];     can[s]=1;     q.push(s);     while (!q.empty())     {           int h=q.front();           q.pop();           vis[h]=0;           for (int i=0;i<g[h].size();++i)           {               if (mi[g[h][i]]>min(mi[h],a[g[h][i]]))               {                   mi[g[h][i]]=min(mi[h],a[g[h][i]]);                   if (!can[g[h][i]])                     can[g[h][i]]=1;                   if (!vis[g[h][i]])                   {                       vis[g[h][i]]=1;                       q.push(g[h][i]);                   }               }           }     }}int main(){    init();    spfa(1);    rspfa(n);    int ans=0;    for (int i=1;i<=n;++i)    if (can[i] && rcan[i])    if (ma[i]!=0 && mi[i]!=0x3f3f3f && ma[i]>=mi[i])      ans=max(ans,ma[i]-mi[i]);    printf("%d",ans);    return 0;}
0 0
原创粉丝点击