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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...