bzoj 1179 Atm

Topic meaning:

A directed graph, some points can be used as end points, each point has a weight, each point and edge can be walked many times, and the weight of the point after the point has passed will not be counted in the score

Starting from a point, find a path that maximizes the score of this path and ends at one of the given points

output this path length

Ideas:

First tarjan shrinks the point

Then use spfa to run the longest road on the new map (beginning very naive thinking that it can be done with dfs

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define ll long long 
10 #define MAXN 500100
11 #define inf 2139062143
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,m,fst[MAXN],nxt[MAXN],to[MAXN],cnt,val[MAXN],bar[MAXN],s,Fst[MAXN],Nxt[MAXN],To[MAXN];
21 int ans,dfn[MAXN],low[MAXN],vis[MAXN],stp,top,st[MAXN],sum[MAXN],ok[MAXN],scc,bl[MAXN];
22 int dis[MAXN],q[MAXN],head,tail;
23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
24 void Add(int u,int v) {Nxt[++cnt]=Fst[u],Fst[u]=cnt,To[cnt]=v;}
25 void tarjan(int x)
26 {
27     dfn[x]=low[x]=++stp,vis[x]=1,st[++top]=x;
28     for(int i=fst[x];i;i=nxt[i])
29         if(!dfn[to[i]]) {tarjan(to[i]);low[x]=min(low[x],low[to[i]]);}
30         else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);
31     if(low[x]==dfn[x])
32     {
33         scc++;int now=0;
34         while(now!=x)
35         {
36             now=st[top--],vis[now]=0,sum[scc]+=val[now],bl[now]=scc;
37             if(bar[now]) ok[scc]=1;
38         }
39     }
40 }
41 void build()
42 {
43     cnt=0;
44     for(int i=1;i<=n;i++)
45         for(int j=fst[i];j;j=nxt[j])
46             if(bl[i]!=bl[to[j]]) Add(bl[i],bl[to[j]]);
47 }
48 void spfa()
49 {
50     s=bl[s],head=tail=1,q[tail]=s,vis[s]=1;
51     while(head<=tail)
52     {
53         int x=q[head++];vis[x]=0;
54         for(int i=Fst[x];i;i=Nxt[i])
55             if(dis[To[i]]<dis[x]+sum[To[i]]) 
56             {
57                 dis[To[i]]=dis[x]+sum[To[i]];
58                 if(!vis[To[i]]) {vis[To[i]]=1,q[++tail]=To[i];}
59             }
60     }
61 }
62 int main()
63 {
64     n=read(),m=read();int a,b,t;
65     while(m--) {a=read(),b=read();add(a,b);}
66     for(int i=1;i<=n;i++) val[i]=read();
67     s=read(),t=read();
68     for(int i=1;i<=t;i++) bar[read()]=1;
69     for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
70     build();spfa();
71     for(int i=1;i<=scc;i++) if(ok[i]) ans=max(ans,dis[i]);
72     printf("%d",ans+sum[s]);
73}
View Code

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325211890&siteId=291194637