24h購物| | PChome| 登入
2012-05-29 21:43:39| 人氣894| 回應0 | 上一篇 | 下一篇

[a462] Beats of the Angel

推薦 0 收藏 0 轉貼0 訂閱站台



內容 :

AB國是一個非常不一樣的國家,在這個國家裡面的人民,他們沒有壽命限制、受傷再嚴重只要時間夠久也能夠恢復、甚至當身體灰飛煙滅後,人民也能從某個固定點復活,彷彿線上遊戲般砍掉也能重練。但也如線上遊戲般,大部分的人民沒有自主意識,有如NPC般遵守規律的作息,只有少部分的人才能隨自我意志來行動。

因為人們長生不死,偶而還會伴隨著新同伴的加入(原因不明,推測是在固定復活點處隨機產生,只是產生出來的人大部分都是NPC),這群人無所事事便想搞破壞(因為根本不會死),於是AB國在創建初期是毫無秩序的,直到「天使」現身。

「天使」是依照旨意下來管理AB國的人民(也就是從重生點出生),能力強大,若是有不遵守規矩的人民,他都能以最快的速度找到並制伏,最高紀錄曾經一天引發數次 Legendary ,可謂極其兇惡。

於是原來具有自主意識的人們(又復活了)開始團結起來,名為「英雄戰線聯盟」,為了恢復昔日的自由,與天使互相對抗。

在一次的戰役中,「戰線聯盟」發現天使出現在一處基地的前方不遠處,而那個基地正巧在進行著重要的會議,主要的領導都在裡面商討戰略,無法現身抵抗天使,因此在基地外守衛的你,必須盡快想出辦法,拖延到最多的時間,並祈禱內部的會議能盡早結束。

於是在來到AB國之前的你,回憶起曾經修過的程式設計,開始假想基地周圍有 N 處空地,空地之間總共會有M個通道相連,當天使在空地時,因為周圍沒有障礙物,可以展開能力到達這個空地的任意地方,但如果要在空地間移動,必須經由空地之間的通道,在此補充一下,有些人可能認為的的文章有Bug,認為前面我提到了「天使的能力強大」,為何不直接飛進基地就好了呢?理由如下:天使雖然強大,但他的能力最為優秀的只有兩項,一是戰技出眾,二是gank極強(這導因於他有內建GPS,等等這項能力也會有些用處),因而能殺爆全場。

扯回重點,因為每個通道的環境都不太相同,因此天使在通過通道時,會需要消耗一些時間,或多或少,天使當然也知道這回事,趕緊啟動腦內GPS,企圖以最短時間攻入基地。

當然天使的能力在「戰線聯盟」並不是秘密,於是聰明的你,拿起了手上的武器(電腦),也去試著攻擊其中一個通道,讓天使在通過這個通道時,所需時間加倍(你手上只有一台電腦,因此只能攻擊一個通道),當通道通過的時間改變後,天使將會重新計算新的最短通過時間,你的目的就是要讓他後來通過的時間,與原來通過的時間相比,延長時間相差最長。

(後記:雖然大家都及時趕出來對抗天使,但依舊被殺到Legendary滿天飛……

輸入說明 :

 

輸入有多筆測資。

每筆測資第一行有兩正整數 N1 <= N <= 1000)、M1 <= M <= 100000),如題幹所述。此時,空地的編號為 1 ~ N,天使的初始位置在 1,基地在 N 。接著M行,每行有三個正整數 ab1 <= a, b <= N)、w1 <= w <= 10000000),代表空地 a 和空地 b 之間有條通道,通過這條通道的時間為 w

 

輸出說明 :

依題幹所述,輸出新的通過時間與原來通過時間相差的最大值。

範例輸入 :

5 7
2 1 5
1 3 1
3 2 8
3 5 7
3 4 3
2 4 7
4 5 2

範例輸出 :

2

提示 :

出處 :

板橋高中練習題 (管理:m80126colin)


很明顯的, 必須先找到一條最短路徑,
那首先我們會發現只有在最短路徑上的邊上的權值做改變時, 天使才會往更長的方向走,
只要在"其中一條"最短路徑邊上枚舉即可,
因為只可能多條最短路徑上的交集, 因此枚舉一條也會算到交集

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
struct Arc {
    int to, v;
};
typedef vector<Arc>::iterator it;
vector<Arc> nlist[1001];
int dis[1001], dis2[1001];
int used[1001], used2[1001];
int ans = 0;
int spfa2(int, int);
void spfa(int st, int ed) {
    memset(dis, 63, sizeof(dis));
    memset(used, 0, sizeof(used));
    dis[st] = 0;
    queue<int> Q;
    Q.push(st);
    int tn;
    while(!Q.empty()) {
        tn = Q.front();
        used[tn] = 0;
        Q.pop();
        for(it i = nlist[tn].begin(); i != nlist[tn].end(); i++) {
            if(dis[i->to] > dis[tn] + i->v) {
                dis[i->to] = dis[tn] + i->v;
                if(used[i->to] == 0) {
                    used[i->to] = 1;
                    Q.push(i->to);
                }
            }
        }
    }
    Q.push(ed);
    int spath = dis[ed];
    while(!Q.empty()) {
        tn = Q.front();
        Q.pop();
        for(it i = nlist[tn].begin(), j; i != nlist[tn].end(); i++) {
            if(dis[tn] - i->v == dis[i->to]) {
                Q.push(i->to);
                for(j = nlist[i->to].begin(); j != nlist[i->to].end(); j++) {
                    if(j->to == tn && j->v == i->v) {
                        break;
                    }
                }
                if(i->v <= ans)
                    break;
                i->v <<= 1;
                j->v <<= 1;
                int tpath = spfa2(st, ed);
                if(tpath - spath > ans)
                    ans = tpath - spath;
                i->v >>= 1;
                j->v >>= 1;
                break;
            }
        }
    }
}
int spfa2(int st, int ed) {
    memset(dis2, 63, sizeof(dis2));
    memset(used2, 0, sizeof(used2));
    dis2[st] = 0;
    queue<int> Q2;
    Q2.push(st);
    int tn;
    while(!Q2.empty()) {
        tn = Q2.front();
        used2[tn] = 0;
        Q2.pop();
        for(it i = nlist[tn].begin(); i != nlist[tn].end(); i++) {
            if(dis2[i->to] > dis2[tn] + i->v) {
                dis2[i->to] = dis2[tn] + i->v;
                if(used2[i->to] == 0) {
                    used2[i->to] = 1;
                    Q2.push(i->to);
                }
            }
        }
    }
    return dis2[ed];
}
int main() {
    int n, m, i, a, b, w;
    while(scanf("%d %d", &n, &m) == 2) {
        for(i = 1; i <= n; i++)
            nlist[i].clear();
        Arc tmp;
        for(i = 0; i < m; i++) {
            scanf("%d %d %d", &a, &b, &w);
            tmp.to = b, tmp.v = w;
            nlist[a].push_back(tmp);
            tmp.to = a;
            nlist[b].push_back(tmp);
        }
        ans = 0;
        spfa(1, n);
        printf("%d\n", ans);
    }
    return 0;
}

台長: Morris
人氣(894) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: ZeroJudge |
此分類下一篇:[ZJ][模擬] a459. An Easy Language
此分類上一篇:[ZJ] a450. 棒棒糖比身高

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文