BZOJ 1179 [Apio2009]Atm

题目链接

思路,求图中最长路,一开始想着直接跑spfa,之后发现环不会处理,那就先tarjan缩点,之后spfa就好了。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<stack>
 5 #include<queue>
 6 using namespace std;
 7 const int N=500005;
 8 int n,m,cnt,dcnt,tim,s,ans,x[N],y[N],hd[N],val[N],vl[N],bar[N],dfn[N],low[N],belong[N],dis[N];
 9 bool instk[N],b[N];
10 stack<int>stk;
11 queue<int>q;
12 struct edge
13 {
14     int to,nxt;
15 }v[N];
16 void addedge(int x,int y)
17 {
18     v[++cnt].nxt=hd[x];
19     v[cnt].to=y;
20     hd[x]=cnt;
21 }
22 void tarjan(int u)
23 {
24     dfn[u]=low[u]=++tim;
25     stk.push(u);
26     instk[u]=1;
27     for(int i=hd[u];i;i=v[i].nxt)
28         if(!dfn[v[i].to])
29         {
30             tarjan(v[i].to);
31             low[u]=min(low[u],low[v[i].to]);
32         }
33         else if(instk[v[i].to])
34             low[u]=min(low[u],dfn[v[i].to]);
35     if(low[u]==dfn[u])
36     {
37         ++dcnt;
38         while(1)
39         {
40             int t=stk.top();
41             stk.pop();
42             instk[t]=0;
43             belong[t]=dcnt;
44             vl[dcnt]+=val[t];
45             if(t==u)
46                 break;
47         }
48     }
49 }
50 int main()
51 {
52     scanf("%d%d",&n,&m);
53     for(int i=1;i<=m;i++)
54     {
55         scanf("%d%d",&x[i],&y[i]);
56         addedge(x[i],y[i]);
57     }
58     for(int i=1;i<=n;i++)
59         scanf("%d",val+i);
60     scanf("%d%d",&s,bar);
61     for(int i=1;i<=bar[0];i++)
62         scanf("%d",bar+i);
63     for(int i=1;i<=n;i++)
64         if(!dfn[i])
65             tarjan(i);
66     cnt=0;
67     memset(hd,0,sizeof(hd));
68     memset(v,0,sizeof(v));
69     for(int i=1;i<=m;i++)
70         if(belong[x[i]]!=belong[y[i]])
71             addedge(belong[x[i]],belong[y[i]]);
72     dis[belong[s]]=vl[belong[s]];
73     b[belong[s]]=1;
74     q.push(belong[s]);
75     while(!q.empty())
76     {
77         int u=q.front();
78         q.pop();
79         b[u]=0;
80         for(int i=hd[u];i;i=v[i].nxt)
81             if(dis[v[i].to]<dis[u]+vl[v[i].to])
82             {
83                 dis[v[i].to]=dis[u]+vl[v[i].to];
84                 if(!b[v[i].to])
85                 {
86                     q.push(v[i].to);
87                     b[v[i].to]=1;
88                 }
89             }
90     }
91     for(int i=1;i<=bar[0];i++)
92         ans=max(ans,dis[belong[bar[i]]]);
93     printf("%d
",ans);
94     return 0;
95 }
View Code
原文地址:https://www.cnblogs.com/fantasquex/p/9363870.html