nyoj 247 虚拟的城市之旅

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=247 

这是第三届省赛的题,一直不会做,今天看了下其他的博客感觉挺好理解的,就照着写了下。

View Code
  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <queue>
  5 using namespace std;
  6 const int MAXM=1000500;
  7 const int MAXN=100100;
  8 struct node{
  9     int y,next;
 10 }edge[MAXM],edge1[MAXM];
 11 int visit[MAXN],dfn[MAXN],low[MAXN];
 12 int head[MAXN],head1[MAXN],id[MAXN],key[MAXN];
 13 int max_pre[MAXN],min_pre[MAXN],stack[MAXN];
 14 int ideax,res,N,num,top,n,s,t;
 15 void init()
 16 {
 17     memset(head,-1,sizeof(head));
 18     memset(head1,-1,sizeof(head1));
 19     memset(dfn,0,sizeof(dfn));
 20     memset(low,0,sizeof(low));
 21     memset(visit,0,sizeof(visit));
 22     res=N=ideax=top;
 23 }
 24 void add(int x,int y)//建图
 25 {
 26     edge[N].y=y;
 27     edge[N].next=head[x];
 28     head[x]=N++;
 29 }
 30 int max(int x,int y)
 31 {
 32     if(x>y)return x;
 33     else return y;
 34 }
 35 int min(int x,int y)
 36 {
 37     if(x>y)return y;
 38     else return x;
 39 }
 40 void DFS(int u) 
 41 {
 42     int i,v,maxmax,minmin;
 43     dfn[u]=low[u]=ideax++;
 44     visit[u]=1;
 45     stack[++top]=u;
 46     for(i=head[u];i!=-1;i=edge[i].next)
 47     {
 48         v=edge[i].y;
 49         if(!dfn[v])
 50         {
 51             DFS(v);
 52             low[u]=min(low[u],low[v]);
 53         }
 54         else if(visit[v]&&dfn[v]<low[u])
 55             low[u]=dfn[v];
 56     }
 57     
 58     if(dfn[u]==low[u])
 59     {
 60         res++;
 61         maxmax=0,minmin=1000;
 62         do{
 63             v=stack[top--];
 64             visit[v]=0;
 65             if(v==1)s=res;
 66             if(v==n)t=res;
 67             id[v]=res;
 68             if(key[v]>maxmax)maxmax=key[v]; //在一个连通分量里边求最大值
 69             if(key[v]<minmin)minmin=key[v]; //在一个连通分量里边求最小值
 70         }while(v!=u);
 71         max_pre[res]=maxmax;
 72         min_pre[res]=minmin;
 73     }
 74 }
 75 void tarjan()  //求强连通
 76 {
 77     int i;
 78     for(i=1;i<=n;i++)
 79         if(!dfn[i])
 80             DFS(i);
 81 }
 82 
 83 int solve()
 84 {
 85     int i,u,v,j;
 86     tarjan();
 87     num=0;
 88     for(i=1;i<=n;i++)    //对缩点建图
 89         for(j=head[i];j!=-1;j=edge[j].next)
 90             if(id[i]!=id[edge[j].y]){
 91                 edge1[num].y=id[edge[j].y];
 92                 edge1[num].next=head1[id[i]];
 93                 head1[id[i]]=num++;
 94             }
 95             memset(key,0,sizeof(key));
 96             queue<int>Q;
 97             Q.push(s);
 98             while(!Q.empty())
 99             {
100                 u=Q.front();
101                 Q.pop();
102                 if(u==t)break;
103                 for(j=head1[u];j!=-1;j=edge1[j].next)
104                 {
105                     v=edge1[j].y;
106                     min_pre[v]=min(min_pre[u],min_pre[v]); //到目前为止最小的买入价
107                     key[v]=max(key[u],max_pre[v]-min_pre[v]);//找可以赚的最大钱数
108                     Q.push(v);
109                 }
110             }
111             return key[t];
112 }
113 int main()
114 {
115     int i,m,x,y,z;
116     while(scanf("%d%d",&n,&m)!=EOF)
117     {
118         init();
119         for(i=1;i<=n;i++)
120             scanf("%d",&key[i]);
121         for(i=1;i<=m;i++)
122         {
123             scanf("%d%d%d",&x,&y,&z);
124             if(z==1)add(x,y);
125             else {add(x,y);add(y,x);}
126         }
127         printf("%d\n",solve());
128     }
129     return 0;
130 }

 

 

 

posted @ 2012-05-08 19:39  我们一直在努力  阅读(224)  评论(0编辑  收藏  举报