您的位置:首页 > 其它

HDU 5934 tarjan

2016-10-29 21:31 288 查看


Bomb

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)


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.

 

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

 

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

题意:给你n颗地雷,每颗地雷的坐标,半径,引爆需要的值,每颗地雷爆炸会引爆半径范围内的地雷,现在要使所有地雷爆炸,最小花费是多少。

题解:tarjan算法找出所有的强联通分量,然后缩点建图,找入度为0的分量即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define eps 1e-8
typedef long long ll;
struct node{
ll x,y,r,c;
}e[1005];
struct node1{
ll from,to,nex;
}edge[1000005];
ll cnt,head[1005],ans,index,dfn[1005],low[1005],st[1005],top,bccnum,bcc[1005],vis[1005],num[1005],dd[1005];
void add(ll u,ll v){
edge[cnt].from=u;
edge[cnt].to=v;
edge[cnt].nex=head[u];
head[u]=cnt++;
}
void tarjan(ll root){
dfn[root]=low[root]=++index;
st[++top]=root;
ll i;
for(i=head[root];~i;i=edge[i].nex){
ll v=edge[i].to;
if(!dfn[v]){
tarjan(v);
low[root]=min(low[root],low[v]);
}
else if(!bcc[v])low[root]=min(low[root],dfn[v]);
}
if(low[root]==dfn[root]){
bccnum++;
for(;;){
ll x=st[top--];
bcc[x]=bccnum;
vis[x]=1;
if(x==root)break;
}
}
}
int main(){
ll t,cas=1;
scanf("%lld",&t);
while(t--){
ll i,n,j;
bccnum=0;
index=0;
memset(dd,0,sizeof(dd));
top=0;
cnt=0;
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(bcc,0,sizeof(bcc));
memset(low,0,sizeof(low));
memset(num,999999,sizeof(num));
memset(vis,0,sizeof(vis));
scanf("%lld",&n);
for(i=1;i<=n;i++){
scanf("%lld%lld%lld%lld",&e[i].x,&e[i].y,&e[i].r,&e[i].c);
}
for(i=1;i<=n;i++){
for(j=i+1;j<=n;j++){
ll dis=(e[i].x-e[j].x)*(e[i].x-e[j].x)+(e[i].y-e[j].y)*(e[i].y-e[j].y);
if(dis<=e[i].r*e[i].r){
add(i,j);
}
if(dis<=e[j].r*e[j].r){
add(j,i);
}
}
}
ans=0;
for(i=1;i<=n;i++){//图不一定是联通的
if(!vis[i])tarjan(i);
}
for(i=0;i<cnt;i++){
if(bcc[edge[i].from]!=bcc[edge[i].to]){
dd[bcc[edge[i].to]]++;
}
}
for(i=1;i<=n;i++){
num[bcc[i]]=min(e[i].c,num[bcc[i]]);
}
for(i=1;i<=bccnum;i++){
if(!dd[i])ans+=num[i];
}
printf("Case #%lld: %lld\n",cas++,ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: