您的位置:首页 > 其它

HDU 5934 Bomb 【图论缩点】(2016年中国大学生程序设计竞赛(杭州))

2016-10-29 17:30 417 查看


Bomb

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

Total Submission(s): 10    Accepted Submission(s): 3

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

 

Source

2016年中国大学生程序设计竞赛(杭州)

 

Recommend

liuyiding   |   We have carefully selected several similar problems for you:  5943 5942 5941 5940 5939 

 

Statistic | Submit | Discuss | Note

题目链接:

  http://acm.hdu.edu.cn/showproblem.php?pid=5934


题目大意:

  N个炸弹,坐标(x,y),爆炸半径r,人为引爆的代价为c。

  如果一个炸弹在已经爆炸的炸弹的爆炸半径内(上),那么这个炸弹也会被引爆(连锁反应,不需要代价)

  问至少多少代价可以把所有炸弹引爆。

题目思路:

  【图论缩点】

  如果A能引爆B那么A向B连一条边。

  建完图之后用Tarjin或者Kosaraju强连通缩点。

  缩完点之后的图是有向无环图。

  再根据新的点连边,那些入度为0的点即为需要人为引爆的。统计代价即可。

//
//by coolxxx
//#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<iomanip>
#include<map>
#include<stack>
#include<queue>
#include<set>
#include<bitset>
#include<memory.h>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//#include<stdbool.h>
#include<math.h>
#pragma comment(linker,"/STACK:1024000000,1024000000")
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(a) ((a)>0?(a):(-(a)))
#define lowbit(a) (a&(-a))
#define sqr(a) ((a)*(a))
#define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define eps (1e-8)
#define J 10000
#define mod 1000000007
#define MAX 0x7f7f7f7f
#define PI 3.14159265358979323
#define N 1004
#define M 1000004
using namespace std;
typedef long long LL;
double anss;
LL aans;
int cas,cass;
int n,m,lll,ans;
int ll,sz;
int fa
,in
,last
,last1
,num
,cc
;
bool mark
;
struct Point
{
LL x,y,r;
int c;
}p
;
struct xxx
{
int next,to;
}a[M],b[M];
void add(int x,int y)
{
a[++lll].next=last[x];
a[lll].to=y;
last[x]=lll;
}
void link(int x,int y)
{
b[++ll].next=last1[x];
b[ll].to=y;
last1[x]=ll;
}
void dfs1(int now)
{
int i;
mark[now]=1;
for(i=last[now];i;i=a[i].next)
if(!mark[a[i].to])
dfs1(a[i].to);
num[++sz]=now;
}
void dfs2(int now)
{
int i;
mark[now]=1;
fa[now]=m;
cc[m]=min(cc[m],p[now].c);
for(i=last1[now];i;i=b[i].next)
{
if(!mark[b[i].to])
dfs2(b[i].to);
}
}
void kosaraju()
{
int i;
mem(mark,0);sz=0;m=0;
for(i=1;i<=n;i++)
if(!mark[i])
dfs1(i);
mem(mark,0);
for(i=n;i;i--)
{
if(!mark[num[i]])
{
cc[++m]=MAX;
dfs2(num[i]);
}
}
}
int main()
{
#ifndef ONLINE_JUDGEW
// freopen("1.txt","r",stdin);
// freopen("2.txt","w",stdout);
#endif
int i,j,k;
int x,y,z;
// init();
// for(scanf("%d",&cass);cass;cass--)
for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
// while(~scanf("%s",s))
// while(~scanf("%d%d",&n,&m))
{
printf("Case #%d: ",cass);
lll=0;ll=0;ans=0;
mem(in,0);mem(last,0);mem(last1,0);
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%lld%lld%lld%lld",&p[i].x,&p[i].y,&p[i].r,&p[i].c);
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j)continue;
if(sqr(p[i].r)>=sqr(p[i].x-p[j].x)+sqr(p[i].y-p[j].y))
add(i,j),link(j,i);
}
}
kosaraju();
for(i=1;i<=n;i++)
{
for(j=last[i];j;j=a[j].next)
{
if(fa[a[j].to]==fa[i])continue;
in[fa[a[j].to]]++;
}
}
for(i=1;i<=m;i++)
if(!in[i])
ans+=cc[i];
printf("%d\n",ans);
}
return 0;
}
/*
//

//
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐