zoukankan      html  css  js  c++  java
  • HDU-5934-scc

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

    题目大意:

    有n个炸弹,给出他们的坐标(x,y)以及伤害半径r和引爆代价c。

    在炸弹爆炸半径以内以及边缘上的炸弹会被连锁引爆。求最少需要多少的代价引爆所有的炸弹。  

    思路:

    求scc缩点,然后产生若干个DAG,找到每个DAG得起点,对每个起点内的所有点找一个最小的代价点贡献给ans,累加求解就是答案,

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define pii pair<int,int>
     4 #define mp make_pair
     5 const int maxn=1005;
     6 int T,N;
     7 long long x[maxn],y[maxn],r[maxn],c[maxn];
     8 vector<int>g[maxn];
     9 int sum,scc_cnt;
    10 int low[maxn],dfn[maxn],scc[maxn],in[maxn];
    11 stack<int>S;
    12 bool ok(int i,int j){
    13     return (y[i]-y[j])*(y[i]-y[j])+(x[i]-x[j])*(x[i]-x[j])<=r[i]*r[i];
    14 }
    15 void dfs(int u){
    16     low[u]=dfn[u]=++sum;
    17     S.push(u);
    18     for(int v:g[u]){
    19         if(!dfn[v]){
    20             dfs(v);
    21             low[u]=min(low[u],low[v]);
    22         }else if(!scc[v]) low[u]=min(low[u],dfn[v]);
    23     }
    24     if(low[u]==dfn[u]){
    25         ++scc_cnt;
    26         int x=-1;
    27         while(x!=u){
    28             x=S.top();
    29             S.pop();
    30             scc[x]=scc_cnt;
    31         }
    32     }
    33 }
    34 int main(){ 
    35     scanf("%d",&T);
    36     for(int cas=1;cas<=T;++cas){
    37         cin>>N;
    38         sum=scc_cnt=0;
    39         while(!S.empty())S.pop();
    40         for(int i=1;i<=N;++i)
    41         low[i]=dfn[i]=scc[i]=0,
    42         g[i].clear(),scanf("%lld%lld%lld%lld",&x[i],&y[i],&r[i],&c[i]);
    43         for(int i=1;i<=N;++i){
    44             for(int j=1;j<=N;++j){
    45                 if(i==j)continue;
    46                 if(ok(i,j))g[i].push_back(j);
    47             }
    48         }
    49         for(int i=1;i<=N;++i){
    50             if(!dfn[i])dfs(i);
    51         }//puts("---");
    52         for(int i=1;i<=scc_cnt;++i)in[i]=0;
    53         for(int i=1;i<=N;++i){
    54             for(int j:g[i]){
    55                 if(scc[i]==scc[j])continue;
    56                 in[scc[j]]++;
    57             }
    58         }
    59         long long ans=0;
    60         for(int i=1;i<=scc_cnt;++i){
    61             if(in[i]==0){
    62                 long long minc=99999999;
    63                 for(int j=1;j<=N;++j){
    64                     if(scc[j]==i){
    65                         minc=min(minc,c[j]);
    66                     }
    67                 }
    68                 ans+=minc;
    69             }
    70         }
    71         cout<<"Case #"<<cas<<": "<<ans<<endl;
    72     }
    73     return 0;
    74 }

    -

  • 相关阅读:
    Python笔记:PEP8常用编程规范
    Flask笔记:蓝图Blueprint
    Flask笔记:视图函数和类视图
    Flask笔记:url_for
    Python设计模式:单例模式
    Linux网络安全篇,认识防火墙(一)
    Linux网络安全篇,配置Yum源(二),阿里Yum源
    IP地址、子网掩码详解
    Linux网络安全篇,配置Yum源(一),本地Yum源
    Linux网络安全篇,进入SELinux的世界(四)
  • 原文地址:https://www.cnblogs.com/zzqc/p/12168541.html
Copyright © 2011-2022 走看看