HDU 5934 Bomb 強連通分量縮點

2021-08-08 12:22:34 字數 1556 閱讀 4806

題意:

n個炸彈都有乙個座標乙個**半徑以及乙個引爆花費,如果乙個炸彈在另乙個炸彈的**範圍內,則引爆另乙個炸彈,可以導致當前炸彈也**,如果當前炸彈的**範圍有其它未炸的炸彈,那麼也能導致這些炸彈**,以此聯動。

思路:如果i炸彈的**範圍內有j炸彈,則建有向邊i->j,然後縮一下點,每個強連通分量內只要引爆乙個,其它都會炸,所以把最小的花費給這個強連通分量,最後我們只需要引爆所有入度為0的強連通分量,且花費最小。

**:

#include #define ll long long

using namespace std;

const int inf = 0x3f3f3f3f;

const ll mod = 1e9+7;

const ll bas = 1001;

const int maxn = 1005;

const int maxm = 1000005;

struct node edge[maxm];

int no, head[maxn];

int _index, low[maxn], dfn[maxn], s[maxn], top, vis[maxn];

int deg[maxn];

int bcc[maxn], cnt;

queueq;

int n, m;

/*unordered_*/set_hash;

inline void init()

inline void add(int u, int v)

void tarjan(int u)

else if(vis[v]) low[u] = min(low[u], dfn[v]);

}

if(dfn[u] == low[u])

while(s[top+1] != u);

}

} struct point

aw[maxn];

int val[maxn];

ll dis2(point p1, point p2)

int main()

for(int i = 1; i <= n; ++i)

if(!dfn[i]) tarjan(i);

for(int i = 0; i < no; ++i)

} memset(val, 0x3f, sizeof val);

for(int i = 1; i <= n; ++i)

val[bcc[i]] = min(val[bcc[i]], aw[i].c);

ll ans = 0;

for(int i = 1; i <= cnt; ++i)

if(deg[i] == 0) ans += val[i];

printf("case #%d: %lld\n", _, ans);

}

return 0;

}

繼續加油~

HDU5934 Bomb(強連通分量分解)

題意 給出n個炸彈座標 範圍 費用,如果某乙個炸彈在另乙個炸彈的 範圍內 上 那麼該炸彈也能 問引爆所有炸彈最小的費用 思路 強連通分量分解,將所有點縮點,然後引爆所有入度為0的點即為最小費用 include include include includetypedef long long ll c...

HDU 5934 Bomb (強連通分量縮點)

題解 題意 有n個炸彈,每個炸彈具有三個屬性值 座標 x,y 引爆半徑r以及引爆成本c。當引爆一枚炸彈時,這枚炸彈會同時引爆其 半徑內的所有炸彈,問引爆所有炸彈的最小成本。思路 乙個炸彈引爆另乙個炸彈可以看做是一條有向邊,那麼所有炸彈的引爆關係就是乙個有向圖。對於有向圖只要引爆入度為0的點就可以將整...

HDU 5934 Bomb(強連通分量縮點)

題目 顯然可以想到引爆花費最小需要選擇能引爆盡量多的,如果a能引爆b,b能引爆c,一定是引爆a最優。如果有一些點可以相互引爆,那麼就引爆這些點裡花費最小的。能互相引爆 這顯然是乙個強連通分量,因此用tarjan求強連通分量之後,對於每個拓撲序最開頭 入度為0 的連通分量,選擇花費最小的進行引爆,即可...