【(最小权点基)tarjan强连通分量缩点+tarjan模板】HDU 5934 Bomb

【AC】

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 int n;
  5 const int maxn=1e3+2;
  6 const int maxm=1e6+2;
  7 const int inf=0x3f3f3f3f;
  8 struct node
  9 {
 10     double x;
 11     double y;
 12     double r;
 13     int c;
 14 }a[maxn];
 15 struct edge
 16 {
 17     int to;
 18     int nxt;
 19 }e[maxm];
 20 int head[maxn],tot;
 21 int dfn[maxn],low[maxn],id;
 22 int S[maxn],top;
 23 int belong[maxn],num;
 24 int du[maxn];
 25 int w[maxn];
 26 bool vis[maxn];
 27 void init()
 28 {
 29     memset(head,-1,sizeof(head));
 30     tot=0;
 31     id=0;
 32     top=0;
 33     num=0;
 34     memset(dfn,0,sizeof(dfn));
 35     memset(low,0,sizeof(low));
 36     memset(du,0,sizeof(du));
 37     memset(w,inf,sizeof(w));
 38     memset(vis,false,sizeof(vis));
 39 }
 40 void addedge(int u,int v)
 41 {
 42     e[tot].to=v;
 43     e[tot].nxt=head[u];
 44     head[u]=tot++;
 45 }
 46 bool judge(int i,int j)
 47 {
 48     return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y))<=a[i].r;
 49 }
 50 void tarjan(int u)
 51 {
 52     dfn[u]=low[u]=++id;
 53     S[++top]=u;
 54     vis[u]=true;
 55     for(int i=head[u];i!=-1;i=e[i].nxt)
 56     {
 57         int v=e[i].to;
 58         if(!dfn[v])
 59         {
 60             tarjan(v);
 61             low[u]=min(low[u],low[v]);
 62         }
 63         else if(vis[v]) low[u]=min(low[u],dfn[v]);
 64     }
 65     if(dfn[u]==low[u])
 66     {
 67         num++;
 68         while(1)
 69         {
 70             belong[S[top]]=num;
 71             vis[S[top]]=false;
 72             w[num]=min(w[num],a[S[top]].c);
 73             if(S[top--]==u) break;
 74         }
 75     }
 76 }
 77 int main()
 78 {
 79     int T;
 80     scanf("%d",&T);
 81     int cas=0;
 82     while(T--)
 83     {
 84         init();
 85         scanf("%d",&n);
 86         for(int i=1;i<=n;i++)
 87         {
 88             scanf("%lf%lf%lf%d",&a[i].x,&a[i].y,&a[i].r,&a[i].c);
 89         }
 90         for(int i=1;i<=n;i++)
 91         {
 92             for(int j=1;j<=n;j++)
 93             {
 94                 if(j==i) continue;
 95                 if(judge(i,j))
 96                 {
 97                     addedge(i,j);    
 98                 }
 99             }
100         }
101         for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
102         for(int u=1;u<=n;u++)
103         {
104             for(int i=head[u];i!=-1;i=e[i].nxt)
105             {
106                 int v=e[i].to;
107                 if(belong[u]==belong[v]) continue;
108                 du[belong[v]]++;
109             }
110         }
111         int ans=0;
112         for(int i=1;i<=num;i++)
113         {
114             int tmp=inf;
115             if(du[i]==0)
116             {
117                 ans+=w[i];
118             }
119         }
120         printf("Case #%d: %d
",++cas,ans);
121     }
122     return 0;    
123 } 
View Code
原文地址:https://www.cnblogs.com/itcsl/p/7441020.html