【Apio2009】Bzoj1179 Atm

【Apio2009】Bzoj1179 Atm

Position:


List

Description

bzoj1179

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的單向的道路到達其中的至少一個酒吧。

Solution

先Tarjian縮點,變成一個DAG(有向無環圖)不會Tarjan Algorithm的傳送門
接下來就好做了:
1. Dfs直接上,雖然Bzoj不會卡你,可今天考試喪心病狂的數據把我卡成了90
2. 記憶化搜索,f[x]記錄從x走到尾的最大搶錢數,下次再走到這點就可以直接調用,還是比dfs快蠻多。
3. 也可以跑最短路(Spfa or Dijstra)

Code

Dfs

// <atm.cpp> - Tue Sep 20 08:15:49 2016
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc.
// I don't know what this program is.

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define MOD 1000000007
#define INF 1e9
using namespace std;
typedef long long LL;
const int MAXN=100010;
const int MAXM=100010;
inline int max(int &x,int &y) {return x>y?x:y;}
inline int min(int &x,int &y) {return x<y?x:y;}
inline int gi() {
    register int w=0,q=0;register char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')q=1,ch=getchar();
    while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
    return q?-w:w;
}
struct Tarjan{
    static const int N=500010,M=500010;
    int n,m,be,tot,_clock,scc;
    int ne[M],to[M];bool in[N];vector<int>p[N];
    int bar[N],fr[N],low[N],dfn[N],f[N],st[N],s[N],ss[N];
    void add(int u,int v){
        to[++tot]=v;ne[tot]=fr[u];fr[u]=tot;
    }
    void Init(){
        n=gi(),m=gi();
        for(int i=1;i<=m;i++){
            int u=gi(),v=gi();add(u,v);
        }
        for(int i=1;i<=n;i++)ss[i]=gi();
        be=gi(),m=gi();
        for(int i=1;i<=m;i++)bar[i]=gi();
    }
    inline void dfs(int x){
        dfn[x]=low[x]=++_clock;
        st[++tot]=x;in[x]=true;
        for(int o=fr[x];o;o=ne[o])
            if(!dfn[to[o]])dfs(to[o]),low[x]=min(low[x],low[to[o]]);
            else if(in[to[o]])low[x]=min(low[x],low[to[o]]);
        if(dfn[x]==low[x]){
            scc++;
            while(st[tot]!=x){
                f[st[tot]]=scc;in[st[tot]]=false;tot--;
            }
            f[x]=scc;in[x]=false;tot--;
        }
    }
    void src(int x,int now){
        if(now<=f[x])return;f[x]=now;
        int to=p[x].size();
        for(int i=0;i<to;i++)
            src(p[x][i],now+s[p[x][i]]);
    }
    void Work(){
        _clock=tot=scc=0;
        memset(dfn,0,sizeof(dfn));
        memset(in,false,sizeof(in));
        for(int i=1;i<=n;i++)
            if(!dfn[i])dfs(i);
        for(int i=1;i<=n;i++)s[f[i]]+=ss[i];
        for(int i=1;i<=n;i++)
            for(int o=fr[i];o;o=ne[o]){
                if(f[i]==f[to[o]])continue;
                p[f[i]].push_back(f[to[o]]);
            }
        for(int i=1;i<=m;i++)bar[i]=f[bar[i]];
        be=f[be];memset(f,0,sizeof(f));
        src(be,s[be]);int ans=0;
        for(int i=1;i<=m;i++)ans=max(ans,f[bar[i]]);
        printf("%d",ans);
    }
}Tar;
int main()
{
    freopen("atm.in","r",stdin);
    freopen("atm.out","w",stdout);
    Tar.Init();Tar.Work();
    return 0;
}

記憶化搜索

// <atm.cpp> - Tue Sep 20 08:15:49 2016
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc.
// I don't know what this program is.

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define MOD 1000000007
#define INF 1e9
using namespace std;
typedef long long LL;
const int MAXN=100010;
const int MAXM=100010;
inline int max(int &x,int &y) {return x>y?x:y;}
inline int min(int &x,int &y) {return x<y?x:y;}
inline int gi() {
    register int w=0,q=0;register char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')q=1,ch=getchar();
    while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
    return q?-w:w;
}
struct Tarjan{
    static const int N=500010,M=500010;
    int n,m,be,tot,_clock,scc;
    int ne[M],to[M];bool in[N];vector<int>p[N];
    int bar[N],fr[N],low[N],dfn[N],f[N],st[N],s[N],ss[N];
    void add(int u,int v){
        to[++tot]=v;ne[tot]=fr[u];fr[u]=tot;
    }
    void Init(){
        n=gi(),m=gi();
        for(int i=1;i<=m;i++){
            int u=gi(),v=gi();add(u,v);
        }
        for(int i=1;i<=n;i++)ss[i]=gi();
        be=gi(),m=gi();
        for(int i=1;i<=m;i++)bar[i]=gi();
    }
    inline void dfs(int x){
        dfn[x]=low[x]=++_clock;
        st[++tot]=x;in[x]=true;
        for(int o=fr[x];o;o=ne[o])
            if(!dfn[to[o]])dfs(to[o]),low[x]=min(low[x],low[to[o]]);
            else if(in[to[o]])low[x]=min(low[x],low[to[o]]);
        if(dfn[x]==low[x]){
            scc++;
            while(st[tot]!=x){
                f[st[tot]]=scc;in[st[tot]]=false;tot--;
            }
            f[x]=scc;in[x]=false;tot--;
        }
    }
    inline int src(int x){//let every node just go once
        if(in[x])return f[x];in[x]=true;
        int to=p[x].size();
        for(int i=0;i<to;i++)
            f[x]=max(f[x],src(p[x][i]));
        if(f[x]||st[x])f[x]+=s[x];
        return f[x];
    }
    void Work(){
        _clock=tot=scc=0;
        memset(dfn,0,sizeof(dfn));
        memset(in,false,sizeof(in));
        for(int i=1;i<=n;i++)
            if(!dfn[i])dfs(i);
        for(int i=1;i<=n;i++)s[f[i]]+=ss[i];
        for(int i=1;i<=n;i++)
            for(int o=fr[i];o;o=ne[o]){
                if(f[i]==f[to[o]])continue;
                p[f[i]].push_back(f[to[o]]);
            }
        memset(st,0,sizeof(st));memset(in,0,sizeof(0));
        for(int i=1;i<=m;i++)bar[i]=f[bar[i]],st[bar[i]]=1;
        be=f[be];memset(f,0,sizeof(f));
        printf("%d",src(be));
    }
}Tar;
int main()
{
    freopen("atm.in","r",stdin);
    freopen("atm.out","w",stdout);
    Tar.Init();Tar.Work();
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章