bzoj1179

题解再次来自lsj(懒得敲):

对于一个强连通分量, 一定是整个走或者不走, 所以tarjan缩点然后跑dijkstra.

  1 #include<bits/stdc++.h>
  2 #define clr(a,x) memset(a,x,sizeof(a))
  3 #define rep(i,l,r) for(int i=l;i<r;i++)
  4 #define Rep(i,a) rep(i,0,e[a].size())
  5 #define REP(i,a) rep(i,0,e1[a].size())
  6 typedef long long ll;
  7 using namespace std;
  8 int read()
  9 {
 10     char c=getchar();
 11     int ans=0,f=1;
 12     while(!isdigit(c)){
 13         if(c==‘-‘) f=-1;
 14         c=getchar();
 15     }
 16     while(isdigit(c)){
 17         ans=ans*10+c-‘0‘;
 18         c=getchar();
 19     }
 20     return ans*f;
 21 }
 22 struct node{
 23     int d,num;
 24     inline bool operator <(const node&A)const{
 25         return d>A.d;
 26     }
 27 };
 28 const int maxn=500005,inf=0x7fffffff;
 29 bool b[maxn],p[maxn];
 30 int dfstime,cnt,s,k,n,m,w[maxn],low[maxn],pre[maxn],scc[maxn],d[maxn],v[maxn];
 31 stack<int>S;
 32 vector<int>e[maxn];
 33 vector<int>e1[maxn];
 34 priority_queue<node>Q;
 35 void dfs(int a)
 36 {
 37     low[a]=pre[a]=++dfstime;
 38     S.push(a);
 39     Rep(i,a){
 40         if(!pre[e[a][i]]){
 41             dfs(e[a][i]);
 42             low[a]=min(low[a],low[e[a][i]]);
 43         }else if(!scc[e[a][i]]){
 44             low[a]=min(low[a],pre[e[a][i]]);
 45         }
 46     }
 47     if(low[a]==pre[a]){
 48         ++cnt;
 49         int x=0;
 50         while(x!=a){
 51             x=S.top();
 52             S.pop();
 53             scc[x]=cnt;
 54             w[cnt]+=v[x];
 55             b[cnt]|=p[x];
 56         }
 57     }
 58 }
 59 void dijkstra()
 60 {
 61     clr(d,0);
 62     d[scc[s]]=w[scc[s]];
 63     node start;
 64     start.num=scc[s],start.d=w[scc[s]];
 65     Q.push(start);
 66     while(!Q.empty()){
 67         node now=Q.top();
 68         Q.pop();
 69         if(now.d==d[now.num]){
 70             REP(i,now.num){
 71                 if(d[now.num]+w[e1[now.num][i]]>d[e1[now.num][i]]){
 72                     d[e1[now.num][i]]=d[now.num]+w[e1[now.num][i]];
 73                     node next;
 74                     next.d=d[e1[now.num][i]];
 75                     next.num=e1[now.num][i];
 76                     Q.push(next);
 77                 }
 78             }
 79         }
 80     }
 81 }
 82 int main()
 83 {
 84     n=read(),m=read(),cnt=dfstime=0,clr(low,0),clr(pre,0),clr(scc,0),clr(b,0),clr(p,0);
 85     rep(i,0,m){
 86         int from=read(),to=read();
 87         e[from].push_back(to);
 88     }
 89     rep(i,1,n+1) v[i]=read();
 90     s=read(),k=read();
 91     while(k--){
 92         int t=read();
 93         p[t]=1;
 94     }
 95     rep(i,1,n+1){
 96         if(!scc[i]) dfs(i);
 97     }
 98     rep(i,1,n+1){
 99         Rep(j,i){
100             if(scc[i]!=scc[e[i][j]])
101             e1[scc[i]].push_back(scc[e[i][j]]);
102         }
103     }
104     dijkstra();
105     int ans=0;
106     rep(i,1,n+1){
107         if(b[i]) ans=max(ans,d[i]);
108     }
109     printf("%d\n",ans);
110     return 0;
111 }

1179: [Apio2009]Atm

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 1921  Solved: 763
[Submit][Status][Discuss]

Description

Input

第一行包含两个整数N、M。N表示路口的个数,M表示道路条数。接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号。接下来N行,每行一个整数,按顺序表示每个路口处的ATM机中的钱数。接下来一行包含两个整数S、P,S表示市中心的编号,也就是出发的路口。P表示酒吧数目。接下来的一行中有P个整数,表示P个有酒吧的路口的编号

Output

输出一个整数,表示Banditji从市中心开始到某个酒吧结束所能抢劫的最多的现金总数。

Sample Input

6 7
1 2
2 3
3 5
2 4
4 1
2 6
6 5
10
12
8
16
1 5
1 4
4
3
5
6

Sample Output

47

HINT

50%的输入保证N, M<=3000。所有的输入保证N, M<=500000。每个ATM机中可取的钱数为一个非负整数且不超过4000。输入数据保证你可以从市中心沿着Siruseri的单向的道路到达其中的至少一个酒吧。

Source

[Submit][Status][Discuss]

时间: 2024-12-28 21:07:46

bzoj1179的相关文章

【bzoj1179】 Apio2009—Atm

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

[BZOJ1179][APIO2009][强连通分量Tarjan+spfa]ATM

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

[BZOJ1177][BZOJ1178][BZOJ1179]APIO2009解题报告

抱着好奇心态去开始做APIO的往年试题感受一下难度 Oil Description 采油区域 Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井.被拍卖的整块土地为一个矩形区域,被划分为M×N个小块. Siruseri地质调查局有关于Navalur土地石油储量的估测数据.这些数据表示为M×N个非负整数,即对每一小块土地石油储量的估计值. 为了避免出现垄断,政府规定每一个承包商只能承包一个由K×K块相连的土地构成的正方形区域. AoE石油联合公司由三个承包商组

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

【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 缩点+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机中的钱数.接下来

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机中的钱数.接下

【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;

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

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

【强连通分量+spfa】Bzoj1179 Apio2009 Atm

Description Sulotion 显然缩强连通分量,然后求最长路,虽然是DAG但还是有点麻烦,于是用了spfa. Code 重建图_数组写错好多次,感觉做这题也就是练了一下实现. 1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int maxn=5e+5; 5 6 int pre[maxn],low[maxn],clock; 7 int scc[maxn],val[maxn],c