HDU 5934 Bomb(tarjan缩点)
2017-09-19 17:05
357 查看
题意:给你n(n<=1000)个炸弹(x, y, r, c),(x, y)是坐标,r是爆炸半径,c是引爆这个炸弹的花费。问你最少花费多少能引爆所有炸弹。
思路:枚举炸弹i j,如果i能引爆j,就i->j连一条边。然后跑下tarjan并缩点形成一个DAG,我们可以知道入度为0的是必须自身引爆,入度不为0的可以由其他炸弹来引爆,我们只需要求出每个入度为0的缩点中引爆所需的最小花费的那个炸弹,最后加起来求和即可。
代码:
思路:枚举炸弹i j,如果i能引爆j,就i->j连一条边。然后跑下tarjan并缩点形成一个DAG,我们可以知道入度为0的是必须自身引爆,入度不为0的可以由其他炸弹来引爆,我们只需要求出每个入度为0的缩点中引爆所需的最小花费的那个炸弹,最后加起来求和即可。
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e3+5; vector<int> g[maxn]; struct node { ll x, y, r, c; }a[maxn]; int n, dfn[maxn], low[maxn], belong[maxn], in[maxn]; int dfs_clock, scc_cnt; bool is[maxn]; stack<int> s; priority_queue<ll, vector<ll>, greater<ll> > pq[maxn]; void tarjan(int u) { dfn[u] = low[u] = ++dfs_clock; s.push(u); for(int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if(!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if(!belong[v]) low[u] = min(low[u], dfn[v]); } if(low[u] == dfn[u]) { scc_cnt++; while(1) { int x = s.top(); s.pop(); belong[x] = scc_cnt; if(x == u) break; } } } void find_scc() { while(!s.empty()) s.pop(); dfs_clock = scc_cnt = 0; memset(belong, 0, sizeof(belong)); memset(dfn, 0, sizeof(dfn)); for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i); } void solve() { memset(in, 0, sizeof(in)); memset(is, 0, sizeof(is)); for(int u = 1; u <= n; u++) for(int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if(belong[u] != belong[v]) in[belong[v]]++; } for(int i = 1; i <= scc_cnt; i++) if(!in[i]) is[i] = 1; for(int i = 1; i <= n; i++) while(!pq[i].empty()) pq[i].pop(); for(int i = 1; i <= n; i++) { if(is[belong[i]]) pq[belong[i]].push(a[i].c); } ll ans = 0; for(int i = 1; i <= scc_cnt; i++) if(is[i]) ans += pq[i].top(); printf("%lld\n", ans); } int main(void) { int _, ca = 1; cin >> _; while(_--) { scanf("%d", &n); for(int i = 1; i <= n; i++) g[i].clear(); for(int i = 1; i <= n; i++) scanf("%lld%lld%lld%lld", &a[i].x, &a[i].y, &a[i].r, &a[i].c); for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { if(i == j) continue; if((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y) <= a[i].r*a[i].r) g[i].push_back(j); } find_scc(); printf("Case #%d: ", ca++); solve(); } return 0; }
相关文章推荐
- hdu 5934 Bomb【最小点基----Tarjan强连通+缩点染色】
- -----tarjan强连通分量缩点-hdu 5934 -Bomb
- HDU 5934 Bomb (tarjan缩点)
- HDU-5934 Bomb(tarjan缩点+入度0最小和)
- [hdu 5934 Bomb]Tarjan强连通分量
- hdu 5934-建图+tarjan缩点
- HDU-5934 Bomb 缩点
- 【2016-CCPC-B】强连通分量,tarjan(Bomb,hdu 5934)
- 【(最小权点基)tarjan强连通分量缩点+tarjan模板】HDU 5934 Bomb
- HDU 5934 Bomb 【图论缩点】(2016年中国大学生程序设计竞赛(杭州))
- HDU 5934 Bomb 【图论缩点】(2016年中国大学生程序设计竞赛(杭州))
- Tarjan 缩点——HDU 5934
- HDU 5934 Bomb【强联通缩点Tarjian】
- 【HDU】5934 Bomb 强连通分量+缩点
- hdu 3062 Party【2-SAT入门---强连通Tarjan+染色缩点】
- HDU 5934 tarjan
- HDU 3639 Hawk-and-Chicken(Tarjan缩点+反向DFS)
- [HDOJ5934]Bomb(强连通分量,缩点)
- HDU 1827 - Summer Holiday(Tarjan + 缩点 + 计算入度)
- hdu 1827 Summer Holiday【Tarjan缩点】