Bomb
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1362 Accepted Submission(s): 447
Problem Description
There are
N
bombs needing exploding.
Each bomb has three attributes: exploding radius ri , position (xi,yi) and lighting-cost ci which means you need to pay ci cost making it explode.
If a un-lighting bomb is in or on the border the exploding area of another exploding one, the un-lighting bomb also will explode.
Now you know the attributes of all bombs, please use the minimum cost to explode all bombs.
Each bomb has three attributes: exploding radius ri , position (xi,yi) and lighting-cost ci which means you need to pay ci cost making it explode.
If a un-lighting bomb is in or on the border the exploding area of another exploding one, the un-lighting bomb also will explode.
Now you know the attributes of all bombs, please use the minimum cost to explode all bombs.
Input
First line contains an integer
T
, which indicates the number of test cases.
Every test case begins with an integers N , which indicates the numbers of bombs.
In the following N lines, the ith line contains four intergers xi , yi , ri and ci , indicating the coordinate of ith bomb is (xi,yi) , exploding radius is ri and lighting-cost is ci .
Limits
- 1≤T≤20
- 1≤N≤1000
- −108≤xi,yi,ri≤108
- 1≤ci≤104
Every test case begins with an integers N , which indicates the numbers of bombs.
In the following N lines, the ith line contains four intergers xi , yi , ri and ci , indicating the coordinate of ith bomb is (xi,yi) , exploding radius is ri and lighting-cost is ci .
Limits
- 1≤T≤20
- 1≤N≤1000
- −108≤xi,yi,ri≤108
- 1≤ci≤104
Output
For every test case, you should output
'Case #x: y', where
x indicates the case number and counts from
1 and
y is the minimum cost.
Sample Input
1 5 0 0 1 5 1 1 1 6 0 1 1 7 3 0 2 10 5 0 1 4
Sample Output
Case #1: 15
Source
————————————————————————————————————
题目的意思是给出n个炸弹的位置的爆炸半径和点燃花费,一个炸弹爆炸会把他爆照范围内的所有炸弹都点燃,求引爆所有炸弹最小花费
思路:强联通缩点,然后把入度为0的点费用加起来
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
#define MAXN 100100
#define MAXM 1000100
struct node
{
int u,v,next;
} edge[MAXM];
struct point
{
LL x,y,l;
int c;
} p[MAXN];
int dfn[MAXN],low[MAXN],s[MAXN],Stack[MAXN],in[MAXN],block[MAXN],cost[MAXN],du[MAXN];
int cnt,tot,index,bnum;
void init()
{
memset(s,-1,sizeof s);
memset(du,0,sizeof du);
memset(cost,INF,sizeof cost);
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
memset(Stack,0,sizeof Stack);
memset(in,0,sizeof in);
memset(block,0,sizeof block);
cnt=tot=index=bnum=0;
}
int add(int u,int v)
{
edge[cnt].u=u;
edge[cnt].v=v;
edge[cnt].next=s[u];
s[u]=cnt++;
}
void tarjan(int x)
{
dfn[x]=low[x]=++tot;
Stack[++index]=x;
in[x]=1;
for(int i=s[x]; ~i; i=edge[i].next)
{
int v=edge[i].v;
if(!dfn[v])
{
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(in[v])
{
low[x]=min(low[x],low[v]);
}
}
if(dfn[x]==low[x])
{
bnum++;
do
{
cost[bnum]=min(cost[bnum],p[Stack[index]].c);
//printf("%d ",Stack[index]);
block[Stack[index]]=bnum;
in[Stack[index--]]=0;
}
while(Stack[index+1]!=x);
// printf("\n");
}
}
int main()
{
int T,n;
int q=1;
for(scanf("%d",&T); T--;)
{
init();
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%lld%lld%lld%d",&p[i].x,&p[i].y,&p[i].l,&p[i].c);
}
for(int i=1; i<=n; i++)
for(int j=i+1; j<=n; j++)
{
LL dis=(p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y);
if(p[i].l*p[i].l>=dis)
add(i,j);
if(p[j].l*p[j].l>=dis)
add(j,i);
}
for(int i=1; i<=n; i++)
if(!dfn[i])
tarjan(i);
for(int i=0; i<cnt; i++)
{
int x=block[edge[i].u],y=block[edge[i].v];
if(x!=y) du[y]++;
}
int ans=0;
for(int i=1; i<=bnum; i++)
{
if(du[i]==0)
ans+=cost[i];
}
printf("Case #%d: %d\n",q++,ans);
}
return 0;
}