hdu5934Bomb

来源:互联网 发布:广告智能推送人工智能 编辑:程序博客网 时间:2024/06/07 03:58

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

题意:给定二维平面上n个炸弹,每个炸弹有引爆需要的费用,如果一个炸弹引爆那么在它的半径范围内的炸弹也会被引爆(不需要花费),求引爆所有炸弹的最小花费。

分析:每个炸弹向能炸到的炸弹连一条有向边,然后有向图缩点成一个DAG图,那么我们只需要花费引爆所有起点即可。

代码:

#include<map>#include<set>#include<stack>#include<cmath>#include<queue>#include<bitset>#include<math.h>#include<vector>#include<string>#include<stdio.h>#include<cstring>#include<iostream>#include<algorithm>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;typedef double db;typedef long long ll;typedef unsigned int uint;typedef unsigned long long ull;const db eps=1e-5;const int N=1e3+10;const int M=1e6+10;const ll MOD=1000000007;const int mod=1000000007;const int MAX=1000000010;const double pi=acos(-1.0);int tot,w[N],u[N],v[M],pre[M];int x[N],y[N],r[N];void add(int a,int b) {    v[tot]=b;pre[tot]=u[a];u[a]=tot++;}int pd(int a,int b) {    return 1ll*r[a]*r[a]>=1ll*(x[a]-x[b])*(x[a]-x[b])+1ll*(y[a]-y[b])*(y[a]-y[b]);}stack<int>S;int scc_cnt,dfs_clock,head[N],sccno[N];int dfs_scc(int a) {    int i,x,lowa,lowv;    S.push(a);    head[a]=lowa=++dfs_clock;    for (i=u[a];~i;i=pre[i])    if (!head[v[i]]) {        lowv=dfs_scc(v[i]);        lowa=min(lowa,lowv);    } else if (!sccno[v[i]]) lowa=min(lowa,head[v[i]]);    if (head[a]==lowa) {        scc_cnt++;        while (1) {            x=S.top();S.pop();            sccno[x]=scc_cnt;            if (x==a) break ;        }    }    return lowa;}void find_scc(int n) {    scc_cnt=dfs_clock=0;    memset(head,0,sizeof(head));    memset(sccno,0,sizeof(sccno));    for (int i=1;i<=n;i++)    if (!head[i]) dfs_scc(i);}int d[N],mi[N];int main(){    int i,j,n,ca,T,ans;    scanf("%d", &T);    for (ca=1;ca<=T;ca++) {        scanf("%d", &n);        for (i=1;i<=n;i++) scanf("%d%d%d%d", &x[i], &y[i], &r[i], &w[i]);        tot=0;memset(u,-1,sizeof(u));        for (i=1;i<=n;i++)            for (j=1;j<=n;j++)            if (i!=j&&pd(i,j)) add(i,j);        find_scc(n);        for (i=1;i<=scc_cnt;i++) d[i]=0,mi[i]=100000;        for (i=1;i<=n;i++) {            mi[sccno[i]]=min(mi[sccno[i]],w[i]);            for (j=u[i];~j;j=pre[j])            if (sccno[i]!=sccno[v[j]]) d[sccno[v[j]]]++;        }        ans=0;        for (i=1;i<=scc_cnt;i++)        if (d[i]==0) ans+=mi[i];        printf("Case #%d: %d\n", ca, ans);    }    return 0;}


0 0
原创粉丝点击