題意:
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 的連通分量,選擇花費最小的進行引爆,即可...