HDU5934-Bomb

Bomb

                                                                           Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
                                                                                                      Total Submission(s): 1185    Accepted Submission(s): 401


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
 


题意:给你n个炸弹的坐标,爆炸半径和引爆需要的花费,问引爆所有炸弹需要的最少花费

解题思路:可以先建图后进行强联通缩点,然后重新建图后求出每个点引爆的最小花费,将所有入度为0的点需要引爆的最小花费进行求和


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include<cmath>

using namespace std;

#define LL long long
const int INF=0x3f3f3f3f;
const int N=1005;

int n;
struct Edge
{
    int v,nt;
} edge[N*N];
struct node
{
    int w;
    LL x,y,r;
} x[N];
int s[N],cnt;
int dfn[N],low[N],id[N],dep,w[N];
bool vis[N],instack[N];
int res,graph[N][N],in[N];
stack<int>st;

void AddEdge(int u,int v)
{
    edge[cnt].v=v;
    edge[cnt].nt=s[u];
    s[u]=cnt++;
}

void tarjan(int u)
{
    st.push(u);
    instack[u]=true;
    vis[u]=true;
    dfn[u]=low[u]=++dep;
    for(int i=s[u]; ~i; i=edge[i].nt)
    {
        int v=edge[i].v;
        if(!vis[v])
        {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(instack[v])
            low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u])
    {
        int t;
        do
        {
            id[t=st.top()]=res;
            st.pop();
            instack[t]=false;
        }
        while(t!=u);
        res++;
    }
}

void solve()
{
    res=0,dep=0;
    while(!st.empty()) st.pop();
    memset(vis,0,sizeof vis);
    memset(instack,0,sizeof instack);
    for(int i=1; i<=n; i++)
        if(!vis[i]) tarjan(i);
    memset(graph,0,sizeof graph);
    memset(in,0,sizeof in);
    for(int i=1; i<=n; i++)
        for(int j=s[i]; ~j; j=edge[j].nt)
        {
            int v=edge[j].v;
            if(id[i]!=id[v]) graph[id[i]][id[v]]=1,in[id[v]]++;
        }
    memset(w,INF,sizeof w);
    for(int i=1; i<=n; i++)
        w[id[i]]=min(w[id[i]],x[i].w);
    int ans=0;
    for(int i=0; i<res; i++)
        if(!in[i])ans+=w[i];
    printf("%d\n",ans);
}

int main()
{
    int t,cas=0;
    scanf("%d",&t);
    while(t--)
    {
        memset(s,-1,sizeof s);
        scanf("%d",&n);
        cnt=1;
        for(int i=1; i<=n; i++) scanf("%lld%lld%lld%d",&x[i].x,&x[i].y,&x[i].r,&x[i].w);
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                if(i==j) continue;
                if((x[i].x-x[j].x)*(x[i].x-x[j].x)+(x[i].y-x[j].y)*(x[i].y-x[j].y)<=x[i].r*x[i].r)
                    AddEdge(i,j);
            }
        printf("Case #%d: ",++cas);
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值