Tarjan 缩点——HDU 5934
2017-05-06 10:38
323 查看
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5934
题意:给出N个炸弹的坐标爆炸半径还有引爆的花费,求爆炸所有炸弹所需要的最小花费。
分析:我们发现如果炸弹A在B的爆炸范围内,同时炸弹B也在炸弹A的爆炸范围内,那么无论引爆哪一个,都会导致它们俩都爆炸,所以我们可以把A和B当做一个炸弹,花费为最小花费即可。同理,可以延伸到 n 个炸弹,如果引爆这 n 个炸弹中的任意一个,最终都会导致这 n 个炸弹都爆炸,那么也可以把这 n 个炸弹都用一个来替代,并用其中的最小花费来表示。这一步,我们可以用Tarjan缩点来完成。
建边:如果炸弹A能引爆炸弹B,那么建立一条有向边 A→B 。那么在求联通分量退栈的时候,找出最小花费,标记给这个连通块的。然后结束后,我们枚举每一条边,如果它们不在一个联通块里,我们就给指向的那个联通块增加一个入度。最终的花费就是所有入度为0的联通块(必须要引爆的炸弹)的花费和了。
AC代码:
题意:给出N个炸弹的坐标爆炸半径还有引爆的花费,求爆炸所有炸弹所需要的最小花费。
分析:我们发现如果炸弹A在B的爆炸范围内,同时炸弹B也在炸弹A的爆炸范围内,那么无论引爆哪一个,都会导致它们俩都爆炸,所以我们可以把A和B当做一个炸弹,花费为最小花费即可。同理,可以延伸到 n 个炸弹,如果引爆这 n 个炸弹中的任意一个,最终都会导致这 n 个炸弹都爆炸,那么也可以把这 n 个炸弹都用一个来替代,并用其中的最小花费来表示。这一步,我们可以用Tarjan缩点来完成。
建边:如果炸弹A能引爆炸弹B,那么建立一条有向边 A→B 。那么在求联通分量退栈的时候,找出最小花费,标记给这个连通块的。然后结束后,我们枚举每一条边,如果它们不在一个联通块里,我们就给指向的那个联通块增加一个入度。最终的花费就是所有入度为0的联通块(必须要引爆的炸弹)的花费和了。
AC代码:
/************************************************************************* > File Name: B.cpp > Author: Akira > Mail: qaq.febr2.qaq@gmail.com > Created Time: 2017年05月05日 星期五 19时37分48秒 ************************************************************************/ #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cstdlib> #include<algorithm> #include<queue> #include<stack> #include<map> #include<cmath> #include<vector> #include<set> #include<list> #include<ctime> typedef long long LL; typedef unsigned long long ULL; typedef long double LD; #define MST(a,b) memset(a,b,sizeof(a)) #define CLR(a) MST(a,0) #define Sqr(a) ((a)*(a)) using namespace std; #define MaxN 1010 #define MaxM MaxN*1000 #define INF 0x3f3f3f3f #define PI 3.1415926535897932384626 const int mod = 1e9+7; const int eps = 1e-8; #define bug cout << 88888888 << endl; struct Node { int x,y,r,c; }node[MaxN]; int T,N; struct Edge { int u,v,next; }edge[MaxM],e[MaxM]; int cont, head[MaxN]; void add(int u, int v) { edge[cont].u = u; edge[cont].v = v; edge[cont].next = head[u]; head[u] = cont++; } int low[MaxN], dfn[MaxN]; int Stack[MaxN], top; int belong[MaxN]; int vis[MaxN]; int Index, cnt; int cost[MaxN]; void init() { cont = 0; MST(head,-1); MST(cost,INF); MST(dfn, -1); CLR(low); CLR(vis); Index = cnt = 1; top = 0; } void Tarjan(int x) { low[x] = dfn[x] = Index; Index++; Stack[++top] = x; vis[x] = true; for(int i=head[x];i!=-1;i=edge[i].next) { int v = edge[i].v; if(dfn[v] == -1) { Tarjan(v); low[x] = min(low[x], low[v]); } else if(vis[v]) { low[x] = min(low[x], dfn[v]); } } if( low[x] == dfn[x] ) { for(int v = -1;v!=x;top--) { v = Stack[top]; vis[v] = false; belong[v] = cnt; cost[cnt] = min(cost[cnt], node[v].c); } cnt++; } } int in[MaxN]; void solve(int t) { init(); for(int i=1;i<=N;i++) { int xi = node[i].x; int yi = node[i].y; int ri = node[i].r; for(int j=1;j<=N;j++) { if(i==j) continue; LL dis = Sqr((LL)(node[j].x-xi)) + Sqr((LL)(node[j].y-yi)); if( dis<=Sqr((LL)ri) ) { add(i,j); //cout << i << " " << j << endl; } } } for(int i=1;i<=N;i++) if(dfn[i]==-1) Tarjan(i); CLR(in); for(int i=0;i<cont;i++) { int u = edge[i].u; int v = edge[i].v; if(belong[u] != belong[v]) { //cout << u << ": " << belong[u] << endl; //cout << v << ": " << belong[v] << endl; in[belong[v]]++; } } int ans = 0; for(int i=1;i<cnt;i++) { //cout << in[i] << endl; if(in[i]==0) ans += cost[i]; } printf("Case #%d: %d\n", t, ans); } int main() { scanf("%d", &T); for(int t=1;t<=T;t++) { scanf("%d", &N); for(int i=1;i<=N;i++) scanf("%d%d%d%d", &node[i].x, &node[i].y, &node[i].r, &node[i].c); solve(t); } }
相关文章推荐
- hdu 5934 Bomb【最小点基----Tarjan强连通+缩点染色】
- hdu 5934-建图+tarjan缩点
- HDU 5934 Bomb (tarjan缩点)
- HDU 5934 Bomb(tarjan缩点)
- HDU-5934 Bomb(tarjan缩点+入度0最小和)
- -----tarjan强连通分量缩点-hdu 5934 -Bomb
- [hdu 5934 Bomb]Tarjan强连通分量
- [HDU 2767]Proving Equivalences[Tarjan强连通缩点缩点]
- hdu 3836 Equivalent Sets (tarjan缩点)
- hdu 3062 Party【2-SAT入门---强连通Tarjan+染色缩点】
- 【2016-CCPC-B】强连通分量,tarjan(Bomb,hdu 5934)
- hdu 3836 Equivalent Sets 强联通 tarjan缩点
- HDU 1827 Summer Holiday(Tarjan缩点)
- tarjan(hdu 5934)
- HDU - 2767 Proving Equivalences(tarjan缩点)
- HDU 3861 The King’s Problem(tarjan缩点+最小路径覆盖ISAP)
- hdu 3861(tarjan 缩点 + 二分图匹配 求最小路径覆盖
- 【HDU 2767】Proving Equivalences (Tarjan 缩点)
- HDU2767——Tarjan+缩点
- HDU 2767 Proving Equivalences(强连通 Tarjan+缩点)