BZOJ_1179_[Apio2009]Atm_tarjan+spfa
标签:pre body memset nbsp ems == else bsp scan
BZOJ_1179_[Apio2009]Atm_tarjan+spfa
题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1179
分析:
显然有环没法直接最长路,那就缩个点再跑。
酒吧连汇点。
代码:
1 #include 2 #include string.h>
3 #include
4 using namespace std;
5 #define N 500050
6 int head[N],to[N1],nxt[N1],val[N],can[N],cancan[N];
7 int n,m,bel[N],dfn[N],low[N],st[N],top,scc,tot,cnt,S,T;
8 int ins[N],sum[N],X[N],Y[N],Q[N],l,r,dis[N],inq[N];
9 inline void add(int u,int v){
10 to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;
11 }
12 void tarjan(int x){
13 st[top++]=x;ins[x]=1;dfn[x]=low[x]=++tot;
14 for(int i=head[x];i;i=nxt[i]){
15 if(!dfn[to[i]]){
16 tarjan(to[i]);
17 low[x]=min(low[x],low[to[i]]);
18 }else if(ins[to[i]])low[x]=min(low[x],dfn[to[i]]);
19 }
20 if(dfn[x]==low[x]){
21 int t=st[--top];ins[t]=0;
22 bel[t]=++scc;
23 sum[scc]+=val[t];
24 cancan[scc]|=can[t];
25 while(t!=x){
26 t=st[--top];ins[t]=0;
27 bel[t]=scc;
28 sum[scc]+=val[t];
29 cancan[scc]|=can[t];
30 }
31 }
32 }
33 int main(){
34 scanf("%d%d",&n,&m);
35 int x,y;
36 for(int i=1;i){
37 scanf("%d%d",&x,&y);
38 add(x,y);
39 X[i]=x,Y[i]=y;
40 }
41 for(int i=1;i){
42 scanf("%d",&val[i]);
43 }
44 scanf("%d%d",&S,&x);
45 T=n+1;
46 for(int i=1;i){
47 scanf("%d",&y);
48 can[y]=1;
49 }
50 for(int i=1;i){
51 if(!dfn[i])tarjan(i);
52 }
53 memset(head,0,sizeof(head));cnt=0;
54 for(int i=1;i){
55 if(bel[X[i]]!=bel[Y[i]])add(bel[X[i]],bel[Y[i]]);
56 }
57 for(int i=1;iif(cancan[i])add(i,T);
58 S=bel[S];
59 Q[r++]=S;inq[S]=1;dis[S]=sum[S];
60 while(l^r){
61 int x=Q[l++];inq[x]=0;if(l==n+10)l=0;
62 for(int i=head[x];i;i=nxt[i]){
63 if(dis[to[i]]sum[to[i]]){
64 dis[to[i]]=dis[x]+sum[to[i]];
65 if(!inq[to[i]]){
66 inq[to[i]]=1;Q[r++]=to[i];if(r==n+10)r=0;
67 }
68 }
69 }
70 }
71 printf("%d",dis[T]);
72 }
BZOJ_1179_[Apio2009]Atm_tarjan+spfa
标签:pre body memset nbsp ems == else bsp scan
原文地址:https://www.cnblogs.com/suika/p/8457082.html
评论