【BZOJ1179】Atm

tarjan缩点

之后跑一边spfa即可

  1 #include<cstdio>
  2 #include<cstring>
  3 using namespace std;
  4 const int N=500010,novis=-1,over=1,nowvis=0;
  5 int head1[N],head2[N],value[N],n,m,size,ans;
  6 int low[N],dfn[N],flag[N],que[N],sum[N],color[N],
  7     cnt,sig,top;
  8 int zh[N],vis[N],dis[N];
  9 struct fx{
 10     int to,next;
 11 }e1[N],e2[N];
 12 int min(int,int),max(int,int),read();
 13 void dfs(int),tarjan(),rebuild(),spfa(int);
 14 void uni2(int,int),uni(int,int);
 15 int main(){
 16     int x,y,p,tmp,s;
 17     memset(head1,0,sizeof(head1));
 18     size=ans=0;
 19     n=read();m=read();
 20     for (int i=1;i<=m;i++){
 21         x=read();y=read();
 22         uni(x,y);
 23     }
 24     for (int i=1;i<=n;i++)
 25         value[i]=read();
 26     s=read();p=read();
 27     tarjan();
 28     spfa(color[s]);
 29     for (int i=1;i<=p;i++){
 30         tmp=read();
 31         ans=max(ans,dis[color[tmp]]);
 32     }
 33     printf("%d",ans);
 34     return 0;
 35 }
 36 void uni(int x,int y){
 37     size++;
 38     e1[size].next=head1[x];
 39     head1[x]=size;
 40     e1[size].to=y;
 41 }
 42 void uni2(int x,int y){
 43     size++;
 44     e2[size].next=head2[x];
 45     head2[x]=size;
 46     e2[size].to=y;
 47 }
 48 void tarjan(){
 49     sig=cnt=top=0;
 50     memset(flag,novis,sizeof(flag));
 51     memset(color,0,sizeof(color));
 52     memset(sum,0,sizeof(sum));
 53     for (int i=1;i<=n;i++)
 54         if (flag[i]==novis) dfs(i);
 55     rebuild();
 56 }
 57 void dfs(int x){
 58     flag[x]=nowvis;
 59     low[x]=dfn[x]=++sig;
 60     que[++top]=x;
 61     for (int e=head1[x];e;e=e1[e].next){
 62         int v=e1[e].to;
 63         if (flag[v]==novis){
 64             dfs(v);
 65             low[x]=min(low[x],low[v]);
 66         }
 67         else if (flag[v]==nowvis)
 68             low[x]=min(low[x],dfn[v]);
 69     }
 70     if (low[x]==dfn[x]){
 71         cnt++;int t;
 72         do{
 73             t=que[top--];
 74             flag[t]=over;
 75             color[t]=cnt;
 76             sum[cnt]+=value[t];
 77         }while (t!=x);
 78     }
 79 }
 80 void rebuild(){
 81     int v;size=0;
 82     for (int u=1;u<=n;u++)
 83         for (int e=head1[u];e;e=e1[e].next){
 84             v=e1[e].to;
 85             if (color[u]!=color[v])
 86                 uni2(color[u],color[v]);
 87         }
 88 }
 89 void spfa(int st){
 90     int r,l,u,v;
 91     memset(vis,0,sizeof(vis));
 92     memset(dis,0,sizeof(dis));
 93     r=1;l=0; zh[l]=st; vis[st]=1;
 94     dis[st]=sum[st];
 95     while (l<=r){
 96         u=zh[l++];
 97         if (l==N) l=0;
 98         for (int e=head2[u];e;e=e2[e].next){
 99             v=e2[e].to;
100             if (dis[v]<dis[u]+sum[v]){
101                 dis[v]=dis[u]+sum[v];
102                 if (!vis[v]){
103                     vis[v]=1;zh[r++]=v;
104                     if (r==N) r=0;
105                 }
106             }
107          }
108          vis[u]=0;
109     }
110 }
111 int min(int x,int y){
112     return x<y?x:y;
113 }
114 int max(int x,int y){
115     return x>y?x:y;
116 }
117 int read(){
118     int ss=0;char c;
119     c=getchar();
120     while (c<‘0‘||c>‘9‘) c=getchar();
121     while (c>=‘0‘&&c<=‘9‘){
122         ss=ss*10+c-‘0‘;c=getchar();
123     }
124     return ss;
125 }

STD

时间: 2024-08-24 16:10:25

【BZOJ1179】Atm的相关文章

【BZOJ-1179】Atm Tarjan + SPFA

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

【bzoj1179】 Apio2009—Atm

www.lydsy.com/JudgeOnline/problem.php?id=1179 (题目链接) 题意:给出一张有向图,每个节点有点权.标记一些点,找出一条路径,可以重复经过一条边,使得总点权和最大.重复经过一个点不能重复算点权. Solution  今日考试题,Dijkstra不幸Gi烂.  WARNING:Dijkstra处理最长路时会出现一些不好的情况,所以千万不要用!!  既然可以重复经过一些边,那么一旦经过了某个环,我们一定可以把环上所有的点跑遍,所以做法就很显然了.先Tarj

【bzoj1179】[Apio2009]抢掠计划atm 强连通分量缩点+spfa

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

【BZOJ1179】【Apio2009】Atm 强连通分量缩点+拓扑DP/拓扑最长路 kosaraju+tarjan+dfs转非递归三种代码

题解: 首先第一个阶段, 可以写kosaraju.也可以写tarjan. 这两种还都分递归和dfs转非递归. ----------------------------------四种方案. 第二个阶段,可以写拓扑DP 也可以写最长路 ----------------------------------乘上之前的,,八种方案. 本文写了kosaraju递归版,tarjan递归版,kosaraju非递归版. --只怪学校oj系统栈太小..都是逼得啊. 代码1(tarjan): #include <c

【Tarjan】+【SPFA】【APIO2009】Atm

一.算法介绍 tarjan——求解有向图强连通分量.这个算法在本人的一篇blog中有介绍,这里就不赘述了.贴上介绍tarjan的的blog链接:http://www.cnblogs.com/Maki-Nishikino/p/5866191.html 那么接下来说说SPFA: SPFA全称Shortest Path Faster Algorithm,用于求解单源最短路.既然名字中有“Faster”,那它就一定有过人之处,事实上它也的确比Dijkstra和Bellman-Ford更高效. 它的思路大

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

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

【动态规划】HDU 5781 ATM Mechine

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5781 题目大意: 一个人有[0,K]内随机的钱,每次可以随意取,但是不知道什么时候取完,取钱超过剩余额度会警告一次,最多警告不能超过W.求期望取出钱的次数. 题目思路: [动态规划] 二分居然错了...看来二分出的答案不一定最优..起码第三个样例过不去. f[i][j]表示钱在[0,i]区间内,警告次数不超过j的期望取钱次数.那么取一次钱k相当于把钱分成两块,[0,k]和[k+1,i],即[0,k

【Spring-Security】【1】认证和授权

[认证] 凭据为基础的认证: 当你登录 e-mail 账号时,你可能提供你的用户名和密码.E-mail的提供商会将你的用户名与数据中的记录进行匹配,并验证你提供的密码与对应的记录是不是匹配.这些凭证(用户名和密码,译者注)就是 e-mail 系统用来鉴别你是一个合法用户的. 两要素认证: 当你想从自动柜员机取钱的时候,你在被允许取钱和做其他业务前,你必须先插卡并输入你的密码.这种方式的认证与用户名和密码的认证方式很类似,与之不同的是用户名信息被编码到卡的磁条上了.联合使用物理磁卡和用户输入密码能

UOJ #2. 【NOI2014】起床困难综合症 数位DP

第二次做NOI的题... .预处理+数位DP #2. [NOI2014]起床困难综合症 id=2" style="">统计提交情况 id=2#tab-statement" style="color:rgb(85,85,85); text-decoration:none; position:relative; display:block; padding:10px 15px; margin-right:2px; line-height:1.428571