HDU - 5934 BOMB (考的是Tarjan的强连通)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <time.h>
#define maxn 1010
using namespace std;
typedef long long ll;
const int N = 1e6 + 15;
struct node
{
    
    
    int x, y, r, c;
}bomb[N] ;
struct edge
{
    
    
    int v, next;
} e[N << 2];
int head[N], cnt;
inline void Add(int u, int v)
{
    
    
    e[cnt].v = v;
    e[cnt].next = head[u];
    head[u] = cnt++;
}
int dfn[N], low[N], id, col, belong[N];
int cost[N];
stack<int > sk;
bool book[N];
inline void Tarjan(int u)
{
    
    
    dfn[u] = low[u] = id++;
    sk.push(u);
    book[u] = 1;
    for (int i = head[u]; i != -1; i = e[i].next) {
    
    
        int v = e[i].v;
        if (!dfn[v]) {
    
    
            Tarjan(v);
            low[u] = min(low[u], low[v]);
        } else if (book[v]) {
    
    
            low[u] = min(low[u], dfn[v]);
        }
    }
    if (low[u] == dfn[u]) {
    
    
        col++;
        int v;
        do
        {
    
    
            v = sk.top();
            book[v] = 0;
            belong[v] = col;
            cost[col] = min(cost[col], bomb[v].c);
            sk.pop();
        } while (u != v);
    }
}
inline bool Ok(int u, int v)
{
    
    
    double x = bomb[u].x - bomb[v].x;
    double y = bomb[u].y - bomb[v].y;
    if (x * x + y * y <= (double)bomb[u].r * bomb[u].r)
        return 1;
    return 0;
}
inline void Init()
{
    
    
    memset(belong, 0, sizeof(belong));
    memset(cost, 0x3f, sizeof(cost));
    memset(book, 0, sizeof(book));
    memset(low, 0, sizeof(low));
    memset(dfn, 0, sizeof(dfn));
    memset(head, -1, sizeof(head));
    cnt = 1, col = 0;
    id = 1;
}
int main()
{
    
    
    int T, cas = 1;
    scanf("%d", &T);
    while (T--) {
    
    
        Init();
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
    
    
            scanf("%d %d %d %d", &bomb[i].x, &bomb[i].y, &bomb[i].r, &bomb[i].c);;
        }
        for (int i = 1; i <= n; i++) {
    
    
            for (int j = 1; j <= n; j++) {
    
    
                if (i != j && Ok(i, j))
                    Add(i, j);
            }
        }
        for (int i = 1; i <= n; i++) {
    
    
            if (!dfn[i])
                Tarjan(i);
        }
        memset(book, 0, sizeof(book));
        for (int i = 1; i <= n; i++) {
    
    
            for (int j = head[i]; j != -1; j = e[j].next) {
    
    
                int v = e[j].v, x = belong[i], y = belong[v];
                if (x != y)
                    book[y] = 1;
            }
        }
        int ans = 0;
        for (int i = 1; i <= col; i++) {
    
    
            if (!book[i])
                ans += cost[i];
        }
        printf("Case #%d: %d\n", cas++, ans);
    }
    return 0;
}



Guess you like

Origin blog.csdn.net/YingShen_xyz/article/details/111410625