BZOJ 1179: [Apio2009]Atm(tarjan+SPFA)

来源:https://www.cnblogs.com/zwfymqz/archive/2018/02/27/8477032.html
-Advertisement-
Play Games

Description Siruseri 城中的道路都是單向的。不同的道路由路口連接。按照法律的規定, 在每個路口都設立了一個 Siruser i 銀行的 ATM 取款機。令人奇怪的是,Siruseri 的酒吧也都設在路口,雖然並不是每個路口都設有酒吧。Bandit ji 計劃實施 Siruseri ...


Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 4164  Solved: 1838
[Submit][Status][Discuss]

Description

Siruseri 城中的道路都是單向的。不同的道路由路口連接。按照法律的規定, 在每個路口都設立了一個 Siruser i 銀行的 ATM 取款機。令人奇怪的是,Siruseri 的酒吧也都設在路口,雖然並不是每個路口都設有酒吧。Bandit ji 計劃實施 Siruseri 有史以來最驚天動地的 ATM 搶劫。他將從市中心 出發,沿著單向道路行駛,搶劫所有他 途徑的 ATM 機,最終他將在一個酒吧慶 祝他的勝利。使用高超的黑客技術,他獲知了每個 ATM 機中可以掠取的 現金數額。他希 望你幫助他計算從市中心出發最後到達某個酒吧時最多能搶劫的現金總數。他可 以經過同一路口 或道路任意多次。但只要他搶劫過某個 ATM 機後,該 ATM 機 裡面就不會再有錢了。 例如,假設該城中有 6 個 路口,道路的連接情況如下圖所示: 市中心在路口 1,由一個入口符號→來標識,那些有酒吧的路口用雙圈來表示。每個 ATM 機中可取的錢數標在了 路口的上方。在這個例子中,Banditji 能搶 劫的現金總數為 47,實施的搶劫路線是:1-2-4-1-2-3-5。

Input

第一行包含兩個整數N、M。N表示路口的個數,M表示道路條數。 接下來M行,每行兩個整數,這兩個整數都在1到N之間, 第i+1行的兩個整數表示第i條道路的起點和終點的路口編號。 接下來N行,每行一個整數,按順序表示每個路口處的ATM機中的錢數。 接下來一行包含兩個整數S、P,S表示市中心的編號,也就是出發的路口。P表示酒吧數目。 接下來的一行中有P個整數,表示P個有酒吧的路口的編號 N, M<=500000。每個ATM機中可取的錢數為一個非負整數且不超過4000。 輸入數據保證你可以從市中心沿著Siruseri的單向的道路到達其中的至少一個酒吧。

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

 

Source

 

 

思路比較簡單,縮起點來求最長路即可

但是為什麼dijstra不能求最長路??黑人問號.jpg

 

// luogu-judger-enable-o2
#include<cstdio>
#include<stack>
#include<cstring>
#include<algorithm>
#include<queue>
#define Pair pair<int,int>
#define F first
#define S second
using namespace std;
const int MAXN=1e6+10;
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct node
{
    int u,v,w,nxt;
}E[MAXN],edge[MAXN];
int headE[MAXN],numE=1,head[MAXN],num=1;
inline void add_edge(int x,int y)
{
    E[numE].u=x;
    E[numE].v=y;
    E[numE].nxt=headE[x];
    headE[x]=numE++;
}
inline void AddEdge(int x,int y)
{
    edge[num].u=x;
    edge[num].v=y;
    edge[num].nxt=head[x];
    head[x]=num++;
}
int N,M,S,P;
int money[MAXN],pos[MAXN],sum[MAXN];
int vis[MAXN],dfn[MAXN],low[MAXN],color[MAXN],colornum=0,tot=0;
stack<int>s;
void tarjan(int now)
{
    dfn[now]=low[now]=++tot;
    s.push(now);
    vis[now]=1;
    for(int i=headE[now];i!=-1;i=E[i].nxt)
    {
        if(!dfn[E[i].v]) 
            tarjan(E[i].v),low[now]=min(low[now],low[E[i].v]);
        else if(vis[E[i].v]) 
            low[now]=min(low[now],dfn[E[i].v]);
    }
    if(low[now]==dfn[now])
    {
        int h;
        colornum++;
        do
        {
            h=s.top();
            color[h]=colornum;
            sum[colornum]+=money[h];
            vis[h]=0;
            s.pop();
            
        }while(h!=now);
    }
}
int dis[MAXN];
void Dijstra()
{
    memset(dis,0,sizeof(dis));
    memset(vis,0,sizeof(vis));
    priority_queue<Pair>q;
    dis[color[S]]=sum[color[S]];
    q.push(make_pair(dis[color[S]],color[S]));
    while(q.size()!=0)
    {
        while(vis[q.top().S]&&q.size()>0) q.pop();
        int p=q.top().S;
        vis[p]=1;
        for(int i=head[p];i!=-1;i=edge[i].nxt)
            if(vis[edge[i].v]==0&&dis[edge[i].v]<dis[p]+sum[edge[i].v])
                dis[edge[i].v]=dis[p]+sum[edge[i].v],
                q.push(make_pair(dis[edge[i].v],edge[i].v));
    }
    int ans=0;
    for(int i=1;i<=P;i++)
        ans=max(ans,dis[color[pos[i]]]);
    printf("%d",ans);
}
int main()
{
    #ifdef WIN32
    freopen("a.in","r",stdin);
    #else
    #endif
    memset(head,-1,sizeof(head));
    memset(headE,-1,sizeof(headE));
    N=read();M=read();
    for(int i=1;i<=M;i++)
    {
        int x=read(),y=read();
        add_edge(x,y);
    }
    for(int i=1;i<=N;i++) money[i]=read();
    S=read();P=read();
    for(int i=1;i<=P;i++) pos[i]=read(); 
    for(int i=1;i<=N;i++)
        if(!dfn[i]) 
            tarjan(i);
    for(int i=1;i<=numE-1;i++)
        if(color[E[i].u]!=color[E[i].v])    
            AddEdge(color[E[i].u],color[E[i].v]);
    Dijstra();
    return 0;
}
dijstra

 

// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<cstdio>
#include<stack>
#include<cstring>
#include<algorithm>
#include<queue>
#define Pair pair<int,int>
#define F first
#define S second
using namespace std;
const int MAXN=1e6+10;
inline int read()
{
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
struct node
{
    int u,v,w,nxt;
}E[MAXN],edge[MAXN];
int headE[MAXN],numE=1,head[MAXN],num=1;
inline void add_edge(int x,int y)
{
    E[numE].u=x;
    E[numE].v=y;
    E[numE].nxt=headE[x];
    headE[x]=numE++;
}
inline void AddEdge(int x,int y,int z)
{
    edge[num].u=x;
    edge[num].v=y;
    edge[num].w=z;
    edge[num].nxt=head[x];
    head[x]=num++;
}
int N,M,S,P;
int money[MAXN],pos[MAXN],sum[MAXN];
int vis[MAXN],dfn[MAXN],low[MAXN],color[MAXN],colornum=0,tot=0;
stack<int>s;
void tarjan(int now)
{
    dfn[now]=low[now]=++tot;
    s.push(now);
    vis[now]=1;
    for(int i=headE[now];i!=-1;i=E[i].nxt)
    {
        if(!dfn[E[i].v]) 
            tarjan(E[i].v),low[now]=min(low[now],low[E[i].v]);
        else if(vis[E[i].v]) 
            low[now]=min(low[now],dfn[E[i].v]);
    }
    if(low[now]==dfn[now])
    {
        int h;
        colornum++;
        do
        {
            h=s.top();
            color[h]=colornum;
            sum[colornum]+=money[h];
            vis[h]=0;
            s.pop();
            
        }while(h!=now);
    }
}
int dis[MAXN];
void Dijstra()
{
    memset(dis,0,sizeof(dis));dis[color[S]]=sum[color[S]];
    memset(vis,0,sizeof(vis));vis[color[S]]=1;
    queue<int>q;
    q.push(color[S]);
    while(q.size()!=0)
    {
        int p=q.front();q.pop();
        vis[p]=0;
        for(int i=head[p];i!=-1;i=edge[i].nxt)
        {
            if(dis[edge[i].v]<dis[p]+edge[i].w)
            {
                dis[edge[i].v]=dis[p]+edge[i].w;
                if(vis[edge[i].v]==0)
                    vis[edge[i].v]=1,q.push(edge[i].v);
            }
        }
    }
    int ans=0;
    for(int i=1;i<=P;i++)
        ans=max(ans,dis[color[pos[i]]]);
    printf("%d",ans);
}
int main()
{
    #ifdef WIN32
    freopen("a.in","r",stdin);
 //   freopen("a.out","w",stdout);
    #else
    #endif
    memset(head,-1,sizeof(head));
    memset(headE,-1,sizeof(headE));
    N=read();M=read();
    for(int i=1;i<=M;i++)
    {
        int x=read(),y=read();
        add_edge(x,y);
    }
    for(int i=1;i<=N;i++) money[i]=read();
    S=read();P=read();
    for(int i=1;i<=P;i++) pos[i]=read(); 
    for(int i=1;i<=N;i++)
        if(!dfn[i]) 
            tarjan(i);
    for(int i=1;i<=numE-1;i++)
        if(color[E[i].u]!=color[E[i].v])    
            AddEdge(color[E[i].u],color[E[i].v],sum[color[E[i].v]]);
    Dijstra();
    return 0;
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.字體大小 font-sizepx/em/rem px像素 em:根據父級的字體大小有關,1em表示是父級字體大小一致 rem:根據html標簽的字體大小有關,1rem表示和html標簽字體大小一致,預設16px, rem:設置 nrem.表示把字體大小設置成和html標簽的字體大小n陪,如果ht ...
  • css三角形 ...
  • 前言 ES6新增了數據類型Set,它是一種類似數組的數據結構。但它和數組的不同之處在於它的成員都是唯一的,也就是說可以用來去除數組重覆成員。 Set本身是一個構造函數用來生成Set數據結構。 const s=new Set(); 使用add()添加成員。也可以在構造函數中傳入數組作為參數 const ...
  • 模式定義 定義一系列演算法,分別封裝起來,讓它們之間可以呼死去那個替換,此模式讓演算法變化,不會影響到使用演算法的客戶 類圖定義 示例 示例來自於Head First上的鴨子例子,一個鴨子的系統,系統中會出現不同的鴨子,一邊游泳一邊叫。綠頭鴨子會飛,會游泳,正常呱呱叫,橡皮鴨子不會飛不會游泳吱吱叫。後期可 ...
  • 工作流模塊 1.模型管理 :web線上流程設計器、預覽流程xml、導出xml、部署流程 2.流程管理 :導入導出流程資源文件、查看流程圖、根據流程實例反射出流程模型、激活掛起 3.運行中流程:查看流程信息、當前任務節點、當前流程圖、作廢暫停流程、指派待辦人 4.歷史的流程:查看流程信息、流程用時、流 ...
  • 說到面向對象這個破玩意,曾經一度我都處於很懵逼的狀態,那麼面向對象究竟是什麼呢?其實說白了,所謂面向對象,就是基於類這個概念,來實現封裝、繼承和多態的一種編程思想罷了。今天我們就來說一下這其中繼承的問題。 好,先不直接上代碼,而是反手來一波文字說明,捋一捋思路。 曾經一段時間因為javascript ...
  • 各行各業,各個領域,各個渠道,都需要有一系列的完整的風險控制,以保證事情向好的方向發展,而免受不可預估的經濟和財產損失而綽手不及。這時候一套完備的風控系統應運而生,以解決實際在生產業務中的各種難題。作為事物的主體,可以採取各種措施和方法,消滅或減少風險事件發生的各種可能性,或減少風險事件發生時造成的... ...
  • Learning to Rank,即排序學習,簡稱為 L2R,它是構建排序模型的機器學習方法,在信息檢索、自然語言處理、數據挖掘等場景中具有重要的作用。其達到的效果是:給定一組文檔,對任意查詢請求給出反映文檔相關性的文檔排序。本文簡單介紹一下 L2R 的基本演算法及評價指標。 背景 隨著互聯網的快速發 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...