Tarjan + bfs HYSBZ 1179Atm
1179: [Apio2009]Atm
Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 3250 Solved: 1346
[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
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的单向的道路到达其中的至少一个酒吧。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# include <cstdio> # include <cstring> # include <iostream> # include <string> # include <vector> # include <queue> # include <stack> # include < set > # include <algorithm> using namespace std; #define N 500001 stack< int >Sta; queue< int >Que; vector< int >Gra[N],newGra[N]; bool isBar[N],inStack[N]; int low[N],dfn[N],belong[N],money[N],newMoney[N],cnt,Time,start; int maxMoney[N]; void Tarjan( int s) { dfn[s] = low[s] = ++Time; Sta.push(s); inStack[s] = true ; for ( int i= 0 ;i<Gra[s].size();i++) { int j = Gra[s][i]; if (dfn[j] == 0 ){ Tarjan(j); low[s] = min(low[s], low[j]); } else if (inStack[j] == true ){ low[s] = min(low[s], dfn[j]); } } if (dfn[s] == low[s]) { cnt ++; while (!Sta.empty()){ int temp = Sta.top(); Sta.pop(); belong[temp] = cnt; newMoney[cnt] += money[temp]; inStack[temp] = false ; if (temp == s) break ; } } } int spfa() { int ans = 0 ; Que.push(start); memset(maxMoney, 0 ,sizeof(maxMoney)); maxMoney[start] = newMoney[start]; while (!Que.empty()) { int now = Que.front(); Que.pop(); for ( int i = 0 ; i < newGra[now].size(); i++) { int j = newGra[now][i]; if (maxMoney[now] + newMoney[j] > maxMoney[j]) { maxMoney[j] = maxMoney[now] + newMoney[j]; Que.push(j); } if (isBar[j]) ans = max(ans, maxMoney[j]); } } return ans; } int main() { int n,m,a,b,s,p; scanf( "%d%d" ,&n,&m); for ( int i = 0 ; i < m; i++) { /* code */ scanf( "%d%d" ,&a, &b); Gra[a].push_back(b); } for ( int i = 1 ; i <= n; i++) { /* code */ scanf( "%d" ,&money[i]); } scanf( "%d%d" ,&s,&p); memset(inStack, false ,sizeof(inStack)); memset(newMoney, 0 ,sizeof(newMoney)); memset(isBar, false ,sizeof(isBar)); memset(dfn, 0 ,sizeof(dfn)); cnt = Time = 0 ; for ( int i = 1 ; i <= n; i++) if (dfn[i] == 0 ) Tarjan(i); if (cnt == 1 ) {printf( "%d" ,newMoney[cnt]); return 0 ;} for ( int i= 0 ;i<p;i++) { scanf( "%d" , &a); isBar[belong[a]] = true ; } start = belong[s]; for ( int i = 1 ; i <= n; i ++) { for ( int j = 0 ; j < Gra[i].size(); j++){ int k = Gra[i][j]; if (belong[i] != belong[k]){ newGra[belong[i]].push_back(belong[k]); } } } int ans = spfa(); printf( "%d" , ans); } |
![](https://images2017.cnblogs.com/blog/966473/201707/966473-20170730153709443-1008920428.jpg)
看起来,STL和链式向前星相比,速度还是慢了不少的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# include <cstdio> # include <cstring> # include <iostream> # include <string> # include <vector> # include <queue> # include <stack> # include < set > # include <algorithm> using namespace std; #define N 500001 stack< int >Sta; queue< int >Que; struct edge { int u,v,next; }edge1[N],edge2[N]; bool isBar[N],inStack[N]; int low[N],dfn[N],belong[N],money[N],newMoney[N],cnt,Time,start; int maxMoney[N],head[N],head2[N]; void add( int u, int v, int id) { edge1[id].u = u; edge1[id].v = v; edge1[id].next = head[u]; head[u] = id; } void add2( int u, int v, int id) { edge2[id].u = u; edge2[id].v = v; edge2[id].next = head2[u]; head2[u] = id; } void Tarjan( int s) { dfn[s] = low[s] = ++Time; Sta.push(s); inStack[s] = true ; for ( int u = head[s]; ~u; u = edge1[u].next) { int v = edge1[u].v; if (dfn[v] == 0 ){ Tarjan(v); low[s] = min(low[s], low[v]); } else if (inStack[v] == true ){ low[s] = min(low[s], dfn[v]); } } if (dfn[s] == low[s]) { cnt ++; while (!Sta.empty()){ int temp = Sta.top(); Sta.pop(); belong[temp] = cnt; newMoney[cnt] += money[temp]; inStack[temp] = false ; if (temp == s) break ; } } } int spfa() { int ans = 0 ; Que.push(start); memset(maxMoney, 0 ,sizeof(maxMoney)); maxMoney[start] = newMoney[start]; while (!Que.empty()) { int now = Que.front(); Que.pop(); for ( int u = head2[now]; ~u; u = edge2[u].next) { int v = edge2[u].v; if (maxMoney[now] + newMoney[v] > maxMoney[v]) { maxMoney[v] = maxMoney[now] + newMoney[v]; Que.push(v); } if (isBar[v]) ans = max(ans, maxMoney[v]); } } return ans; } int main() { int n,m,a,b,s,p; scanf( "%d%d" ,&n,&m); memset(head,- 1 ,sizeof(head)); for ( int i = 0 ; i < m; i++) { /* code */ scanf( "%d%d" ,&a, &b); add(a,b,i+ 1 ); } for ( int i = 1 ; i <= n; i++) { /* code */ scanf( "%d" ,&money[i]); } scanf( "%d%d" ,&s,&p); memset(inStack, false ,sizeof(inStack)); memset(newMoney, 0 ,sizeof(newMoney)); memset(isBar, false ,sizeof(isBar)); memset(dfn, 0 ,sizeof(dfn)); cnt = Time = 0 ; for ( int i = 1 ; i <= n; i++) if (dfn[i] == 0 ) Tarjan(i); if (cnt == 1 ) {printf( "%d" ,newMoney[cnt]); return 0 ;} for ( int i= 0 ;i<p;i++) { scanf( "%d" , &a); isBar[belong[a]] = true ; } start = belong[s]; memset(head2,- 1 ,sizeof(head2)); int kkk = 0 ; for ( int i = 1 ; i <= n; i ++) { for ( int u = head[i]; ~u; u = edge1[u].next){ int v = edge1[u].v; if (belong[i] != belong[v]){ add2(belong[i],belong[v],++kkk); } } } int ans = spfa(); printf( "%d" , ans); } |