P1179: [Apio2009]Atm

缩点+spfa最短路,因为最终不可能有环,所以直接spfa。

  1 const maxe=1000001;
  2 type
  3   node=record
  4     f,t:longint;
  5   end;
  6 var n,m,s,i,j,ans,cnt,num,u,x,dgr:longint;
  7 h,he,dfn,low,q,d,v,va,bl:array[0..maxe] of longint;
  8 b,bi:array[0..maxe] of node;
  9 f:array[0..maxe*20] of longint;
 10 p:array[0..maxe] of boolean;
 11 function min(a,b:longint):longint;
 12 begin
 13   if a>b then exit(b) else exit(a);
 14 end;
 15 procedure insert(u,v:longint);
 16 begin
 17   with bi[i] do
 18     begin
 19       f:=he[u];
 20       t:=v;
 21     end;
 22   he[u]:=i;
 23 end;
 24 procedure reinsert(u,v:longint);
 25 begin
 26   inc(cnt);
 27   with b[cnt] do
 28     begin
 29       f:=h[u];
 30       t:=v;
 31     end;
 32   h[u]:=cnt;
 33 end;
 34 procedure readd;
 35 var i,e,v:longint;
 36 begin
 37   cnt:=0;
 38   for i:=1 to n do
 39     begin
 40       e:=he[i];
 41       while e<>0 do
 42         begin
 43           v:=bi[e].t;
 44           if bl[i]<>bl[v] then reinsert(bl[i],bl[v]);
 45           e:=bi[e].f;
 46         end;
 47     end;
 48 end;
 49 procedure tarjan(x:longint);
 50 var e,t,j:longint;
 51 begin
 52   inc(dgr); inc(num);
 53   p[x]:=true; f[num]:=x; dfn[x]:=dgr; low[x]:=dgr;
 54   e:=he[x];
 55   while e<>0 do
 56     begin
 57       t:=bi[e].t;
 58       if dfn[t]=0 then
 59         begin
 60           tarjan(t);
 61           if low[x]>low[t] then low[x]:=low[t];
 62         end
 63       else if (p[t]) and (dfn[t]<low[x]) then low[x]:=dfn[t];
 64       e:=bi[e].f;
 65     end;
 66   if dfn[x]=low[x] then
 67     begin
 68       j:=0; inc(cnt);
 69       while j<>x do
 70         begin
 71           j:=f[num];
 72           dec(num);
 73           p[j]:=false;
 74           bl[j]:=cnt;
 75           //writeln(j,‘   ‘,cnt);
 76           inc(v[cnt],va[j]);
 77         end;
 78     end;
 79 end;
 80 procedure spfa;
 81 var e,t,now,l,r:longint;
 82 begin
 83   fillchar(p,sizeof(p),true);
 84   fillchar(d,sizeof(d),0);
 85   l:=1; r:=1; f[1]:=bl[s]; p[bl[s]]:=false; d[bl[s]]:=v[bl[s]]; //writeln(v[bl[s]]);
 86   while l<=r do
 87     begin
 88       now:=f[l];
 89       e:=h[now];
 90       while e<>0 do
 91         begin
 92           t:=b[e].t;
 93           //if t=1 then writeln(‘x‘,now,‘ ‘,v[t]);
 94           if d[t]<d[now]+v[t] then
 95             begin
 96               d[t]:=d[now]+v[t];
 97               if p[t] then
 98                 begin
 99                   p[t]:=false;
100                   inc(r);
101                   f[r]:=t;
102                 end;
103             end;
104           e:=b[e].f;
105         end;
106       inc(l);
107       p[now]:=true;
108     end;
109 end;
110 begin
111   readln(n,m);
112   for i:=1 to m do
113     begin
114       readln(u,x);
115       insert(u,x);
116     end;
117   for i:=1 to n do readln(va[i]);
118   fillchar(p,sizeof(p),false);
119   for i:=1 to n do if dfn[i]=0 then tarjan(i);
120   readln(s,m);
121   readd;
122   //for i:=1 to 4 do writeln(v[i]);
123   spfa;
124   for i:=1 to m do
125     begin
126       read(u);
127       if d[bl[u]]>ans then ans:=d[bl[u]];
128     end;
129   writeln(ans);
130 end.

(转载请注明出处:http://www.cnblogs.com/Kalenda/)

时间: 2024-10-12 17:36:57

P1179: [Apio2009]Atm的相关文章

1179: [Apio2009]Atm

1179: [Apio2009]Atm Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1629  Solved: 615[Submit][Status] Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一个整数,按顺序表示每个路口处的ATM机中的钱数.接下来一行包含两个整数S

bzoj1179: [Apio2009]Atm

tarjan缩点就是DAG上求最长路把...然而我并不会求...只会写spfa了... #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> #include<stack> #include<queue> using namespace std; #define rep(i,s,t) for(int i=s;i<=t;i++) #defin

BZOJ1179 : [Apio2009]Atm 缩点+spfa

1179: [Apio2009]Atm Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 2069  Solved: 826[Submit][Status][Discuss] Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一个整数,按顺序表示每个路口处的ATM机中的钱数.接下来

BZOJ 1179: [Apio2009]Atm( tarjan + 最短路 )

对于一个强连通分量, 一定是整个走或者不走, 所以tarjan缩点然后跑dijkstra. --------------------------------------------------------------------- #include<bits/stdc++.h> #define rep(i, n) for(int i = 0; i < n; ++i) #define clr(x, c) memset(x, c, sizeof(x)) #define foreach(i,

tarjan+spfa最短路 BZOJ1179 [Apio2009] Atm

1179: [Apio2009]Atm Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 3641  Solved: 1552[Submit][Status][Discuss] Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一个整数,按顺序表示每个路口处的ATM机中的钱数.接下

缩点+spfa最长路【bzoj】 1179: [Apio2009]Atm

[bzoj] 1179: [Apio2009]Atm Description Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是,Siruseri 的酒吧也都设在路口,虽然并不是每个路口都设有酒吧.Banditji 计划实施 Siruseri 有史以来最惊天动地的 ATM 抢劫.他将从市中心 出发,沿着单向道路行驶,抢劫所有他 途径的 ATM 机,最终他将在一个酒吧庆 祝他的胜利.使用高超

bzoj 1179: [Apio2009]Atm

Description Input 第 一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路 的起点和终点的路口编号.接下来N行,每行一个整数,按顺序表示每个路口处的ATM机中的钱数.接下来一行包含两个整数S.P,S表示市中心的编号,也就 是出发的路口.P表示酒吧数目.接下来的一行中有P个整数,表示P个有酒吧的路口的编号 Output 输出一个整数,表示Banditji从市中心开始到某个酒吧结束所能抢劫的

bzoj 1179[Apio2009]Atm (tarjan+spfa)

题目 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一个整数,按顺序表示每个路口处的ATM机中的钱数.接下来一行包含两个整数S.P,S表示市中心的编号,也就是出发的路口.P表示酒吧数目.接下来的一行中有P个整数,表示P个有酒吧的路口的编号 输出 输出一个整数,表示Banditji从市中心开始到某个酒吧结束所能抢劫的最多的现金总数. 样例输入 6 7 1

【强连通分量&#183;Tarjan】bzoj1179: [Apio2009]Atm

新博的第一发! 因为这几天切了几道强连通分量,所以从这里begin [题目描述] Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定,在每个路口都设立了一个Siruseri 银行的ATM 取款机.令人奇怪的是,Siruseri的酒吧也都设在路口,虽然并不是每个路口都设有酒吧.Banditji 计划实施Siruseri 有史以来最惊天动地的ATM 抢劫.他将从市中心出发,沿着单向道路行驶,抢劫所有他途径的ATM 机,最终他将在一个酒吧庆祝他的胜利.使用高超的黑客技术,他获