BZOJ1179 [APIO2009] ATM

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1179

Description

Input

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

Output

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

Tarjan缩点后跑一遍最长路就出解了

造了个轮子

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <queue>
 6 #include <stack>
 7 #define rep(i,l,r) for(int i=l; i<=r; i++)
 8 #define clr(x,y) memset(x,y,sizeof(x))
 9 #define travel(x) for(Edge *p=last[x]; p; p=p->pre)
10 #define travel2(x) for(Edge *p=last2[x]; p; p=p->pre)
11 using namespace std;
12 const int maxn = 500010;
13 inline int read(){
14     int ans = 0, f = 1;
15     char c = getchar();
16     for(; !isdigit(c); c = getchar())
17     if (c == '-') f = -1;
18     for(; isdigit(c); c = getchar())
19     ans = ans * 10 + c - '0';
20     return ans * f;
21 }
22 struct Edge{
23     Edge *pre; int to;
24 }edge[500010],edge2[500010];
25 Edge *last[maxn], *last2[maxn], *pt = edge, *pt2 = edge2;
26 int n,m,x,y,dfsclock=0,tmp=0,scc=0,S,P,c[maxn],dfn[maxn],low[maxn],belong[maxn],v[maxn],d[maxn];
27 bool ins[maxn],inq[maxn];
28 stack <int> s; queue <int> q;
29 inline void addedge(int x,int y){
30     pt->pre = last[x]; pt->to = y; last[x] = pt++; 
31 }
32 inline void addedge2(int x,int y){
33     pt2->pre = last2[x]; pt2->to = y; last2[x] = pt2++; 
34 }
35 void tarjan(int x){
36     low[x] = dfn[x] = ++dfsclock; ins[x] = 1; s.push(x);
37     travel(x){
38         if (!dfn[p->to]){
39             tarjan(p->to);
40             low[x] = min(low[x],low[p->to]);
41         }
42         else if (ins[p->to]) low[x] = min(low[x],dfn[p->to]);
43     }
44     if (dfn[x] == low[x]){
45         scc++;
46         while (tmp != x){
47             tmp = s.top(); s.pop();
48             belong[tmp] = scc; v[scc] += c[tmp]; ins[tmp] = 0;
49         }
50     }
51 }
52 void rebuild(){
53     rep(i,1,n) travel(i){
54         if (belong[i] != belong[p->to])
55         addedge2(belong[i],belong[p->to]);
56     }
57 }
58 void spfa(){
59     while (!q.empty()) q.pop();
60     q.push(belong[S]); inq[belong[S]] = 1; clr(d,-1); d[belong[S]] = v[belong[S]];
61     while (!q.empty()){
62         int now = q.front(); q.pop();
63         travel2(now){
64             if (d[p->to] < d[now] + v[p->to]){
65                 d[p->to] = d[now] + v[p->to];
66                 if (!inq[p->to]) q.push(p->to);
67             }
68         }
69     }
70 }
71 int main(){
72     n = read(); m = read(); clr(last,0); clr(last2,0);
73     rep(i,1,m){
74         x = read(); y = read(); addedge(x,y);
75     }
76     rep(i,1,n) c[i] = read();
77     rep(i,1,n) if (!dfn[i]) tarjan(i);
78     rebuild();
79     S = read(); P = read();
80     spfa();
81     int ans = -1;
82     rep(i,1,P){
83         x = read();
84         ans = max(ans,d[belong[x]]);
85     }
86     printf("%d\n",ans);
87     return 0;
88 }
View Code

 

posted on 2016-01-20 11:01  ACMICPC  阅读(168)  评论(0编辑  收藏  举报

导航