码迷,mamicode.com
首页 > 其他好文 > 详细

Tarjan + bfs HYSBZ 1179Atm

时间:2017-07-30 16:58:24      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:body   container   log   algo   cto   iostream   center   online   idt   

1179: [Apio2009]Atm

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 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

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);
}


 
技术分享
 看起来,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);
}

Tarjan + bfs HYSBZ 1179Atm

标签:body   container   log   algo   cto   iostream   center   online   idt   

原文地址:http://www.cnblogs.com/liwenchi/p/7259323.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!