zoukankan      html  css  js  c++  java
  • [HDOJ5934]Bomb(强连通分量,缩点)

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

    题意:有n个炸弹,爆炸范围和点燃花费给你,如果一个爆炸那么它爆炸范围内的炸弹也会爆炸。问让所有炸弹爆炸的最小花费。

    遍历任意两个炸弹,如果i在j的爆炸范围内,则建一条有向边。缩完点以后找入度为0的点点燃就行了。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 typedef long long LL;
      5 typedef struct Edge {
      6     int u;
      7     int v;
      8     int next;
      9     Edge() { next = -1; }
     10 }Edge;
     11 typedef struct P {
     12     LL x, y, r;
     13     int c;
     14 }P;
     15 const int maxn = 1510;
     16 P p[maxn];
     17 
     18 int head[maxn], ecnt;
     19 Edge edge[maxn*maxn];
     20 int n, m;
     21 
     22 int bcnt, dindex;
     23 int dfn[maxn], low[maxn];
     24 int stk[maxn], top;
     25 int belong[maxn];
     26 bool instk[maxn];
     27 int ret[maxn];
     28 int in[maxn];
     29 
     30 void init() {
     31     memset(edge, 0, sizeof(edge));
     32     memset(head, -1, sizeof(head));
     33     memset(instk, 0, sizeof(instk));
     34     memset(dfn, 0, sizeof(dfn));
     35     memset(low, 0, sizeof(low));
     36     memset(belong, 0, sizeof(belong));
     37     ecnt = top = bcnt = dindex = 0;
     38 }
     39 
     40 void adde(int uu, int vv) {
     41     edge[ecnt].u = uu;
     42     edge[ecnt].v = vv;
     43     edge[ecnt].next = head[uu];
     44     head[uu] = ecnt++;
     45 }
     46 
     47 void tarjan(int u) {
     48     int v = u;
     49     dfn[u] = low[u] = ++dindex;
     50     stk[++top] = u;
     51     instk[u] = 1;
     52     for(int i = head[u]; ~i; i=edge[i].next) {
     53         v = edge[i].v;
     54         if(!dfn[v]) {
     55             tarjan(v);
     56             low[u] = min(low[u], low[v]);
     57         }
     58         else if(instk[v]) low[u] = min(low[u], dfn[v]);
     59     }
     60     if(dfn[u] == low[u]) {
     61         bcnt++;
     62         do {
     63             v = stk[top--];
     64             instk[v] = 0;
     65             belong[v] = bcnt;
     66         } while(v != u);
     67     }
     68 }
     69 
     70 LL dis(P a, P b) {
     71     LL l1 = a.x - b.x;
     72     LL l2 = a.y - b.y;
     73     return l1 * l1 + l2 * l2;
     74 }
     75 
     76 int main() {
     77     // freopen("in", "r", stdin);
     78     int T, _ = 1;
     79     scanf("%d", &T);
     80     while(T--) {
     81         scanf("%d", &n);
     82         init();
     83         memset(in, 0, sizeof(in));
     84         for(int i = 1; i <= n; i++) ret[i] = 10000000;
     85         for(int i = 1; i <= n; i++) {
     86             scanf("%I64d%I64d%I64d%d",&p[i].x,&p[i].y,&p[i].r,&p[i].c);
     87         }
     88         for(int i = 1; i <= n; i++) {
     89             for(int j = 1; j <= n; j++) {
     90                 if(i == j) continue;
     91                 LL d = dis(p[i], p[j]);
     92                 if(d <= (LL)p[i].r * p[i].r) adde(i, j);
     93             }
     94         }
     95         for(int i = 1; i <= n; i++) {
     96             if(!dfn[i]) tarjan(i);
     97         }
     98         for(int i = 0; i < ecnt; i++) {
     99             int u = edge[i].u, v = edge[i].v;
    100             if(belong[u] != belong[v]) in[belong[v]]++;
    101         }
    102         for(int i = 1; i <= n; i++) {
    103             ret[belong[i]] = min(ret[belong[i]], p[i].c);
    104         }
    105         int tot = 0;
    106         for(int i = 1; i <= bcnt; i++) {
    107             if(!in[i]) tot += ret[i];
    108         }
    109         printf("Case #%d: ", _++);
    110         printf("%d
    ", tot);
    111     }
    112     return 0;
    113 }
  • 相关阅读:
    sublime开启vim模式
    git命令行界面
    搬进Github
    【POJ 2886】Who Gets the Most Candies?
    【UVA 1451】Average
    【CodeForces 625A】Guest From the Past
    【ZOJ 3480】Duck Typing
    【POJ 3320】Jessica's Reading Problemc(尺取法)
    【HDU 1445】Ride to School
    【HDU 5578】Friendship of Frog
  • 原文地址:https://www.cnblogs.com/kirai/p/6017215.html
Copyright © 2011-2022 走看看