hdu5934 Bomb(强连通缩点)

思路:n^2枚举每个炸弹能炸到的炸弹建图,然后跑强连通缩点并且维护这个点的最小花费,缩完点之后的图是一颗有向树,那么直接从入度为0的点开始炸即可


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
#define LL long long
struct Node
{
	LL x,y;
	LL r;
	int c;
}a[maxn];
vector<int>e[maxn];
int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
int maxc[maxn];
stack<int>s;
void dfs(int u)
{
	pre[u]=lowlink[u]=++dfs_clock;
	s.push(u);
	for(int i = 0;i<e[u].size();i++)
	{
		int v = e[u][i];
		if(!pre[v])
		{
			dfs(v);
			lowlink[u]=min(lowlink[u],lowlink[v]);
		}
		else if(!sccno[v])
			lowlink[u]=min(lowlink[u],pre[v]);
	}
	if(lowlink[u]==pre[u])
	{
		scc_cnt++;
		for(;;)
		{
			int x = s.top();s.pop();
			sccno[x]=scc_cnt;
			maxc[scc_cnt]=min(maxc[scc_cnt],a[x].c);
			if(x==u)break;
		}
	}
}
void find_scc(int n)
{
	dfs_clock=scc_cnt=0;
	memset(sccno,0,sizeof(sccno));
	memset(pre,0,sizeof(pre));
	while(!s.empty())
		s.pop();
	for(int i = 1;i<=n;i++)
		if(!pre[i])
			dfs(i);
}
bool check(int i,int j)
{
	double d = sqrt(1.0*(a[i].x-a[j].x)*(a[i].x-a[j].x)+1.0*(a[i].y-a[j].y)*(a[i].y-a[j].y));
	if(1.0*a[i].r>=d)return true;
	return false;
}
int in[maxn];
vector<int>G[maxn];
int ans = 0;
int main()
{
    int T,cas=1;
	scanf("%d",&T);
	while(T--)
	{
		ans = 0;
		memset(in,0,sizeof(in));

        int n;
		scanf("%d",&n);
		for(int i = 0;i<=n;i++)e[i].clear();
		for(int i = 1;i<=n;i++)
			scanf("%lld%lld%lld%d",&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(check(i,j))
				{  
					e[i].push_back(j);
				}
			}
		}
		for(int i = 0;i<=n;i++)
			maxc[i]=1e9;
        find_scc(n);
		for(int i = 0;i<=n;i++)G[i].clear();
		for(int u=1;u<=n;u++)
		{
			for(int i = 0;i<e[u].size();i++)
			{
				int v = e[u][i];
				if(sccno[u]!=sccno[v])
				{
					in[sccno[v]]++;
					G[sccno[u]].push_back(sccno[v]);
				}
			}
		}
        for(int i = 1;i<=scc_cnt;i++)
		{
			if(!in[i])
			{	
				ans+=maxc[i];
			}
		}
		printf("Case #%d: ",cas++);
		printf("%d\n",ans);
	}
}


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
1T20
1N1000
108xi,yi,ri108
1ci104
 

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
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值