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 }