NYOJ 247

View Code
  1 /*
  2 思路:
  3 利用最短路的变形
  4 分别从起点搜一次
  5 从终点搜一次
  6 从起点搜出从起点到达各点的最小值
  7 从终点搜出从终点到达各点的最大值(所有可以到达的点)
  8 
  9 主要思想是:
 10 从  1  到  i  再从 i 到  n
 11 从 1 到 i 时 路径是正着存的
 12 
 13 从i 到  n 时我们把路径反着存一次
 14 变成求  从 n  到 i 了(此处最重要) 
 15 */
 16 #include<iostream>
 17 #include<cstdio>
 18 #include<cstring>
 19 #include<queue>
 20 #define qmax(a,b) ((a)>(b))?(a):(b)
 21 #define qmin(a,b) ((a)<(b))?(a):(b)
 22 using namespace std;
 23 
 24 const int roadnum=500001;
 25 const int citynum=100001;
 26 struct node
 27 {
 28    int e;
 29    int next; 
 30 }edge[roadnum*2];
 31 
 32 int k1[citynum],k2[citynum];
 33 bool flag1[citynum],flag2[citynum];
 34 int maxval[citynum],minval[citynum];
 35 int n,m;
 36 int k=0;
 37 queue <int> q;
 38 
 39 void ADD(int from,int to)
 40 {
 41    edge[k].e=to;
 42    edge[k].next=k1[from];
 43    k1[from]=k++;
 44    
 45    edge[k].e=from;
 46    edge[k].next=k2[to];
 47    k2[to]=k++;
 48 }
 49 
 50 void init()
 51 {
 52    int i,x,y,z;
 53    memset(flag1,0,sizeof(flag1));
 54    memset(flag2,0,sizeof(flag2));
 55    memset(k1,-1,sizeof(k1));//从起点搜索用 
 56    memset(k2,-1,sizeof(k2));//从终点搜索用 
 57    for(i=1;i<=n;++i)
 58     {
 59        scanf("%d",&minval[i]);
 60        maxval[i]=minval[i];
 61     }
 62    while(m--)
 63     {
 64        scanf("%d%d%d",&x,&y,&z);
 65        ADD(x,y);
 66        if(2==z)ADD(y,x); 
 67     }
 68 }
 69 
 70 int spfa()
 71 {
 72   int x,y,i;
 73   while(!q.empty())q.pop();
 74   q.push(1);
 75   flag1[1]=1;
 76   while(!q.empty())// 这个while()  控制从 从起点 可以到达的所有点可以取的最小值 
 77    {
 78      x = q.front();
 79      q.pop();
 80      for(i=k1[x];i!=-1;i=edge[i].next)
 81       {
 82          y= edge[i].e;
 83          minval[y]=qmin(minval[x],minval[y]);
 84          if(!flag1[y])
 85           {
 86             q.push(y);
 87             flag1[y]=1;
 88           }
 89       }
 90    }
 91    
 92    q.push(n);
 93    flag2[n]=1;
 94    while(!q.empty())// 因为路径反着存了一次  我们从终点 逆向搜回去  可以到达各点的最大值 
 95     {              //相当于从各点走到终点的最大值(因为路径反存了一次) 
 96        x = q.front();
 97        q.pop();
 98        for(i=k2[x];i!=-1;i=edge[i].next)
 99         {
100            y = edge[i].e;
101            maxval[y]=qmax(maxval[x],maxval[y]);
102            if(!flag2[y])
103             {
104               q.push(y);
105               flag2[y]=1;
106             }
107         }
108     }
109   int te=0;
110   for(i=1;i<=n;++i)
111    if(flag1[i] && flag2[i] && maxval[i]-minval[i]>te)// flag1[i]!=0表明从起点可以到这个点 
112     te=maxval[i]-minval[i];                   //flag2[i]!=0表明从点 i 可以到达终点 
113   return te;
114 }
115 
116 int main()
117 {
118    while(EOF != scanf("%d%d",&n,&m))
119     {
120        init();
121        printf("%d\n",spfa());
122     }
123    return 0;
124 }

 

posted @ 2012-05-07 19:06  知行执行  阅读(203)  评论(0编辑  收藏  举报