bzoj 1179[Apio2009]Atm (tarjan+spfa)

来源:http://www.cnblogs.com/haizhe/archive/2016/09/16/5868091.html
-Advertisement-
Play Games

題目 輸入 第一行包含兩個整數N、M。N表示路口的個數,M表示道路條數。接下來M行,每行兩個整數,這兩個整數都在1到N之間,第i+1行的兩個整數表示第i條道路的起點和終點的路口編號。接下來N行,每行一個整數,按順序表示每個路口處的ATM機中的錢數。接下來一行包含兩個整數S、P,S表示市中心的編號,也 ...


題目

輸入

第一行包含兩個整數N、M。N表示路口的個數,M表示道路條數。接下來M行,每行兩個整數,這兩個整數都在1到N之間,第i+1行的兩個整數表示第i條道路的起點和終點的路口編號。接下來N行,每行一個整數,按順序表示每個路口處的ATM機中的錢數。接下來一行包含兩個整數S、P,S表示市中心的編號,也就是出發的路口。P表示酒吧數目。接下來的一行中有P個整數,表示P個有酒吧的路口的編號

輸出

輸出一個整數,表示Banditji從市中心開始到某個酒吧結束所能搶劫的最多的現金總數。

樣例輸入

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
樣例輸出

47
提示

50%的輸入保證N, M<=3000。所有的輸入保證N, M<=500000。每個ATM機中可取的錢數為一個非負整數且不超過4000。輸入數據保證你可以從市中心沿著Siruseri的單向的道路到達其中的至少一個酒吧。
View Code

 這道題我們需要用tarjan+spfa(用來跑最長路)

 首先要做的是把圖上的點跑一邊tarjan求出所有的強連通分量,把強連通分量上的點的父節點都設成該強連通分量的根

              //因為強連通分量上的點只要能到達一個就可以到達該強連通分量上的其它點,並且一條路可以走很多遍。

 再把所有強連通分量中的除了根以外的點上的值全部加到根上。

 然後將所有不在強連通分量中的點以及所有強連通分量的根為新的點,重新建圖

 對新建的圖進行spfa求最長路

 最後找出所有酒吧的父節點找出來,找出這些節點中到起點值最大的

              //因為強連通分量上的點只要能到達一個就可以到達該強連通分量上的其它點,並且一條路可以走很多遍。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int cnt, hh[510000], hhh[510000], stack[510000];
int dfn[510000], low[510000], num, ans, q, top, w[510000];
int father[510000], dd[510000], j, n, h, t, l[510000], z, x, y, m, s, p;
bool d[510000];
struct node
{
    int v, next;
};
node b[510000], ss[510000];
void add(int aa, int bb)//連邊
{
    b[++cnt].v = bb;
    b[cnt].next = hh[aa];
    hh[aa] = cnt;
}
void addd(int aa, int bb)//連接新建圖上的邊
{
    ss[++cnt].v = bb;
    ss[cnt].next = hhh[aa];
    hhh[aa] = cnt;
}



void tarjan(int k)
{
    int i;
    dfn[k] = low[k] = ++num;
    stack[++top] = k;
    d[k] = true;
    for(i = hh[k]; i != 0; i = b[i].next)
    {
        int e = b[i].v;
        if(!dfn[e])
        {
            tarjan(e);
            low[k] = min(low[k], low[e]);
        }
        else if(d[e] == true)
        {
            low[k] = min(low[k], dfn[e]);
        }
    }
    if(dfn[k] == low[k])
    {
        d[k] = false;
        father[k] = k;
        while(stack[top] != k)
        {
            w[k] += w[stack[top]];
            father[stack[top]] = k;
            d[stack[top--]] = false;
        }
        top--;
    }

}
void rebuild()
{
    cnt = 0;
    int i;
    for(i = 1; i <= n; i++)
    {
        for(j = hh[i]; j != 0; j = b[j].next)
        {
            t = b[j].v;
            if(father[i] == father[t])continue;
            addd(father[i], father[t]);
        }
    }
}
void spfa()
{
    int i;
    q = s;
    memset(d, 0, sizeof(d));
    h = 0, t = 0;
    l[q] = w[q];
    d[q] = true;
    while(1)
    {
        if(h > t)break;

        for(i = hhh[q]; i != 0; i = ss[i].next)
        {
            z = ss[i].v;
            if(l[q] + w[z] > l[z])
            {
                l[z] = l[q] + w[z];
                if(d[z])continue;
                dd[++t] = z;
                d[z] = true;
            }
        }
        d[q] = false;
        q = dd[++h];
    }
}
int main()
{
    int i;
    scanf("%d %d", &n, &m);
    for(i = 1; i <= m; i++)
    {
        scanf("%d %d", &x, &y);
        add(x, y);
    }
    for(i = 1; i <= n; i++)
    {
        scanf("%d", &w[i]);
    }
    scanf("%d %d", &s, &p);
    for(j = 1; j <= n; j++)
    {
        if(!dfn[j])tarjan(j);
    }
    rebuild();//利用tarjan求出所有強連通分量

    s = father[s];//如果起點在一個強連通分量中,那麼將起點換成該強連通分量的根
//因為強連通分量上的點只要能到達一個就可以到達該強連通分量上的其它點,並且一條路可以走很多遍。
//重要的事說三遍
spfa();//利用spfa求出最長路
for(i = 1; i <= p; i++) { scanf("%d", &q); ans = max(ans, l[father[q]]); } printf("%d", ans); return 0; }

 

 

 

 


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

-Advertisement-
Play Games
更多相關文章
  • 1.python中有一些基本規則的特殊字元。 (1)#表示這後的字元為python註釋。 (2)\n標準的行分隔符。 (3)\繼續上一行。(也就是過長的語句可以使用反斜杠(\)分解成幾行) (4);將兩個語句連接在一行。 (5):將代碼的頭和體分開。(多個語句構成一個代碼塊(代碼組),像if,whi ...
  • 如:/application/uctenter/controller 如:/application/uctenter/controller/User.php class User{ //屬性 public userName; //駝峰命名首字母小寫 //私有屬性 private _userAge;  ...
  • Counter(計數器) 是一個字典的子類,存儲形式同樣為字典,其中存儲的鍵為字典的元素,值為元素出現的次數,在使用之前我們需要先導入文件 import collections 初始化一個計數器 most_common(self,n) 取出元素最多的前n項 sorted(c) 給計數器排序 ''.j ...
  • 由於Django是動態網站,所有每次請求均會去數據進行相應的操作,當程式訪問量大時,耗時必然會更加明顯,最簡單解決方式是使用:緩存,緩存將一個某個views的返回值保存至記憶體或者memcache中,5分鐘內再有人來訪問時,則不再去執行view中的操作,而是直接從記憶體或者Redis中之前緩存的內容拿到 ...
  • 利用django的Q()功能可以很好的展開搜索功能 假設我要做個這樣的搜索功能 那麼思路是怎麼樣的? 那我們就來看看代碼 前端的代碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title ...
  • 今天看到園友心白水撰寫的《簡單翻譯工具--必應字典第三方API使用方法》,感覺很不錯,所以用Python也寫了一個。源碼如下: 程式運行的結果如下: 請輸入英文單詞: python美音:[ 'paɪθɑn ] 英音:[ 'paɪθ(ə)n ] n. 蟒;蚺蛇Web 蟒蛇;巨蟒;派森 例句en: Se ...
  • 分類 分類可以模塊化方法的定義,可以用於向現有的類添加新的方法。 分類提供了一種簡單的方式,用他可以將類的定義模塊化到相關方法的組或分類中。它還提供了拓展現有類定義的簡便方式,並且不必訪問類的源代碼,也無需創建子類。 分類可以通過兩種方法來實現: 1.繼承自一個分類:可以通過將分類名稱括在類名稱之後 ...
  • 題目鏈接 http://vjudge.net/contest/132391#problem/G Description standard input/outputStatements — It' s a good game, — Princess said pensively. It was cle ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...