luogu1073 最优贸易 (tarjan+dp)

tarjan缩点,然后按照拓扑序,做1号点能到达的点的答案
具体做法是对每个点记一个min[i],max[i],vis[i]和ans[i]
做拓扑序的时候,假设在从u点开始做,有边u到v,如果vis[u]=1,则则
vis[v]=1(初始时vis[bel[1]]=1);
更新在v点及以前买进的最小进价:min[v]=min{min[v],min[u]}
统计在v点卖出的答案:ans[v]=max{ans[u],ans[v],max[v]-min[v]}
则最后答案就是ans[bel[N]]

貌似还有做两遍spfa的做法...不管了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 #include<vector>
 6 #define LL long long int
 7 #define inf 0x3f3f3f3f
 8 using namespace std;
 9 const int maxn=100010,maxm=1000010;
10 
11 LL rd(){
12     LL x=0;char c=getchar();int neg=1;
13     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
14     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
15     return x*neg;
16 }
17 
18 int N,M;
19 int eg[maxm][2],egh[maxn],ect;
20 int eg2[maxm][2],egh2[maxn],ect2;
21 int val[maxn],in[maxn],bel[maxn];
22 int dfn[maxn],low[maxn],stk[maxn],sct,tot,pct;
23 int mi[maxn],ma[maxn],ans[maxn];
24 vector<int> hav[maxn];
25 bool instk[maxn],flag[maxn],vis[maxn];
26 
27 inline void adeg(int a,int b){
28     eg[ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect++;
29 }
30 inline void adeg2(int a,int b){
31     eg2[ect2][0]=b;eg2[ect2][1]=egh2[a];egh2[a]=ect2++;
32     in[b]++;
33 }
34 
35 void tarjan(int x){
36     dfn[x]=low[x]=++tot;instk[x]=1;stk[++sct]=x;
37     for(int i=egh[x];i!=-1;i=eg[i][1]){
38         int j=eg[i][0];
39         if(instk[j]) low[x]=min(low[x],dfn[j]);
40         else if(!dfn[j]) {
41             tarjan(j);low[x]=min(low[x],low[j]);
42         }
43     }if(dfn[x]==low[x]){
44         pct++;mi[pct]=inf;ma[pct]=-inf;
45         while(sct){
46             mi[pct]=min(mi[pct],val[stk[sct]]);
47             ma[pct]=max(ma[pct],val[stk[sct]]);
48             bel[stk[sct]]=pct;
49             instk[stk[sct]]=0;
50             hav[pct].push_back(stk[sct]);
51             if(stk[sct--]==x) break;
52         }
53     }
54 }
55 
56 
57 int main(){
58     int i,j,k;
59     //freopen("testdata.in","r",stdin);
60     N=rd(),M=rd();
61     for(i=1;i<=N;i++) val[i]=rd();
62     memset(egh,-1,sizeof(egh));memset(egh2,-1,sizeof(egh2));
63     for(i=1;i<=M;i++){
64         int a=rd(),b=rd(),c=rd();
65         adeg(a,b);if(c==2) adeg(b,a);
66     }for(i=1;i<=N;i++) if(!dfn[i]) tarjan(i);
67     
68     for(i=1;i<=pct;i++){
69         memset(flag,0,pct+5);
70         for(j=0;j<hav[i].size();j++){
71             for(k=egh[hav[i][j]];k!=-1;k=eg[k][1]){
72                 if(i==bel[eg[k][0]]) continue;
73                 if(!flag[bel[eg[k][0]]]) adeg2(i,bel[eg[k][0]]);
74                 flag[bel[eg[k][0]]]=1;
75             }
76         }
77     }
78     queue<int> q;vis[bel[1]]=1;
79     for(i=1;i<=pct;i++){
80         if(!in[i]) q.push(i);
81     }
82     while(!q.empty()){
83         int p=q.front();q.pop();
84         for(i=egh2[p];i!=-1;i=eg2[i][1]){
85             j=eg2[i][0];
86             if(vis[p]){
87                 vis[j]=1;ans[j]=max(ans[j],ans[p]);
88                 mi[j]=min(mi[j],mi[p]);
89                 ans[j]=max(ans[j],ma[j]-mi[j]);
90             }
91             if(!(--in[j])) q.push(j);
92         }
93     }
94     printf("%d\n",ans[bel[N]]);
95 }

 

posted @ 2018-08-02 20:10  Ressed  阅读(299)  评论(0编辑  收藏  举报