Tarjan

来源:互联网 发布:淘宝网十字绣鞋垫 编辑:程序博客网 时间:2024/05/16 14:30

Tarjan

#include<bits/stdc++.h>#define M(a,b) memset(a,b,sizeof(a))#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1using namespace std;const int MAXN=1007;typedef long long LL;struct Targan{    vector<int> G[MAXN];    int pre[MAXN],lowlink[MAXN],sccno[MAXN],dfs_clock,scc_cnt;    stack<int> S;    void init(int n)    {        for(int i=0;i<=n;i++) G[i].clear();        while(!S.empty()) S.pop();    }    void addedge(int a,int b)    {        G[a].push_back(b);    }    void dfs(int u)    {        pre[u]=lowlink[u]=++dfs_clock;        S.push(u);        for(int i=0;i<G[u].size();i++)        {            int v=G[u][i];            if(!pre[v])            {                dfs(v);                lowlink[u]=min(lowlink[u],lowlink[v]);            }            else if(!sccno[v])            {                lowlink[u]=min(lowlink[u],pre[v]);            }        }        if(lowlink[u]==pre[u])        {            scc_cnt++;            while(1)            {                int x=S.top();S.pop();                sccno[x]=scc_cnt;                if(x==u) break;            }        }    }    void find_scc(int n)    {        dfs_clock=scc_cnt=0;        M(sccno,0),M(pre,0);        for(int i=1;i<=n;i++)        {            if(!pre[i])                dfs(i);        }    }}targan;struct Bomb{    double x,y;    double r;    int c;}bomb[MAXN];double GetDis(Bomb a,Bomb b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}int cost[MAXN];int indeg[MAXN];int main(){    int T;scanf("%d",&T);int cas=0;    while(T--)    {        int n;scanf("%d",&n);        targan.init(n);        LL ans=0;        for(int i=1;i<=n;i++)        {            scanf("%lf%lf%lf%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)                {                    if(GetDis(bomb[i],bomb[j])<=bomb[i].r)                    {                        targan.addedge(i,j);                    }                }            }        }        targan.find_scc(n);        memset(indeg,0,sizeof(indeg));        memset(cost,0x3f,sizeof(cost));        for(int i=1;i<=n;i++)        {            for(int j=0;j<targan.G[i].size();j++)            {                if(targan.sccno[i]!=targan.sccno[targan.G[i][j]])                {                    indeg[targan.sccno[targan.G[i][j]]]++;                }            }            cost[targan.sccno[i]]=min(cost[targan.sccno[i]],bomb[i].c);        }        for(int i=1;i<=targan.scc_cnt;i++)        {            if(indeg[i]==0)            {                ans+=cost[i];            }        }        printf("Case #%d: %lld\n",++cas,ans);    }}