欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

HDU 5934 && 2016CCPC杭州 B: Bomb(Trajan强连通)

程序员文章站 2022-04-28 14:49:09
...

HDU 5934 && 2016CCPC杭州 B: Bomb(Trajan强连通)


题意:

坐标系上有n个炸弹,每个炸弹都有不同的爆炸半径,并且爆炸会引起连锁反应,如果一个炸弹爆炸,那么在这个炸弹的爆炸半径内所有的炸弹都会跟着引爆,你要引爆所有的炸弹,引爆每个炸弹都有不同的引爆代价,求最小代价


如果B在A的爆炸半径内,那么A到B连接一条有向边

之后强连通分量+缩点形成一张有向无环图

很显然只要点燃所有入度为0的点中最便宜的炸弹就好了

#include<stdio.h>
#include<string.h>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
#define LL long long
vector<LL> G[1005], Gp[1005];
stack<LL> st;
typedef struct
{
	LL x;
	LL y;
	LL r;
	LL pri;
}Point;
Point s[1005];
LL t, cnt, time[1005], low[1005], vis[1005], scc[1005], cost[1005];
void Trajan(LL x)
{
	LL i, v;
	vis[x] = 1;
	low[x] = time[x] = ++t;
	st.push(x);
	for(i=0;i<G[x].size();i++)
	{
		v = G[x][i];
		if(vis[v]==0)
		{
			Trajan(v);
			low[x] = min(low[x], low[v]);
		}
		else if(scc[v]==0)
			low[x] = min(low[x], time[v]);
	}
	if(low[x]==time[x])
	{
		cnt++;
		while(st.empty()==0)
		{
			v = st.top();
			st.pop();
			scc[v] = cnt;
			cost[cnt] = min(cost[cnt], s[v].pri);
			if(v==x)
				break;
		}
	}
}
void Sech(LL x)
{
	LL i, v;
	vis[x] = 1;
	for(i=0;i<Gp[x].size();i++)
	{
		v = Gp[x][i];
		if(vis[v]==0)
			Sech(v);
	}
}
int main(void)
{
	LL T, n, i, j, v, ans, cas = 1;
	scanf("%lld", &T);
	while(T--)
	{
		scanf("%lld", &n);
		for(i=1;i<=n;i++)
		{
			G[i].clear();
			Gp[i].clear();
			scanf("%lld%lld%lld%lld", &s[i].x, &s[i].y, &s[i].r, &s[i].pri);
		}
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				if(i==j)
					continue;
				if((s[i].x-s[j].x)*(s[i].x-s[j].x)+(s[i].y-s[j].y)*(s[i].y-s[j].y)<=s[i].r*s[i].r)
					G[i].push_back(j);
			}
		}
		cnt = t = 0;
		memset(vis, 0, sizeof(vis));
		memset(scc, 0, sizeof(scc));
		memset(cost, 62, sizeof(cost));
		for(i=1;i<=n;i++)
		{
			if(vis[i]==0)
				Trajan(i);
		}
		for(i=1;i<=n;i++)
		{
			for(j=0;j<G[i].size();j++)
			{
				v = G[i][j];
				if(scc[i]!=scc[v])
					Gp[scc[i]].push_back(scc[v]);
			}
		}
		ans = 0;
		memset(vis, 0, sizeof(vis));
		for(i=cnt;i>=1;i--)
		{
			if(vis[i]==0)
			{
				ans += cost[i];
				Sech(i);
			}
		}
		printf("Case #%lld: %lld\n", cas++, ans);
	}
	return 0;
}

相关标签: 2016CCPC杭州赛区