There are
N
bombs needing exploding.
Each bomb has three attributes: exploding radius ri , position (xi,yi) and lighting-cost ci which means you need to pay ci cost making it explode.
If a un-lighting bomb is in or on the border the exploding area of another exploding one, the un-lighting bomb also will explode.
Now you know the attributes of all bombs, please use the minimum cost to explode all bombs.
Each bomb has three attributes: exploding radius ri , position (xi,yi) and lighting-cost ci which means you need to pay ci cost making it explode.
If a un-lighting bomb is in or on the border the exploding area of another exploding one, the un-lighting bomb also will explode.
Now you know the attributes of all bombs, please use the minimum cost to explode all bombs.
Every test case begins with an integers N , which indicates the numbers of bombs.
In the following N lines, the ith line contains four intergers xi , yi , ri and ci , indicating the coordinate of ith bomb is (xi,yi) , exploding radius is ri and lighting-cost is ci .
Limits
- 1≤T≤20
- 1≤N≤1000
- −108≤xi,yi,ri≤108
- 1≤ci≤104
1 5 0 0 1 5 1 1 1 6 0 1 1 7 3 0 2 10 5 0 1 4
Case #1: 15
题意:
在一个直角坐标系上给你n个炸弹,这些炸弹可以被点燃引爆,或者被其他炸弹给连带。 点燃每个炸弹有一个花费,问引爆所有炸弹最少需要多少个。
解题思路:
首先根据能不能被连带引爆的关系建立有向图。然后发现,只要有入度就一定能被其他节点引爆,没有入度就必须被点燃。
那么就将没有入度的点点燃加起来即可,但是注意可能出现这样的情况,如果成环了, 那么一定要选择一个点,所以我们可以缩点,然后新点的花费就是所有节点的花费中最小的。
缩点后后再统计没有入度花费总和即可
代码:
#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>s;
LL dfs_clock,scc_cnt, pre[1005],low[1005];
LL vis[1005],sccno[1005],cost[1005];
struct Node
{
LL x;
LL y;
LL r;
LL cost;
}node[1005];
void Trajan(LL x)
{
LL i, v;
vis[x]=1;
low[x]=pre[x]=++dfs_clock;
s.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(sccno[v]==0)
low[x] = min(low[x], pre[v]);
}
if(low[x]==pre[x])
{
scc_cnt++;
while(s.empty()==0)
{
v = s.top();
s.pop();
sccno[v]=scc_cnt;
cost[scc_cnt] = min(cost[scc_cnt], node[v].cost);
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", &node[i].x, &node[i].y, &node[i].r, &node[i].cost);
}
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j)
continue;
if((node[i].x-node[j].x)*(node[i].x-node[j].x)+(node[i].y-node[j].y)*(node[i].y-node[j].y)<=node[i].r*node[i].r)
G[i].push_back(j);
}
}
scc_cnt = dfs_clock = 0;
memset(vis, 0, sizeof(vis));
memset(sccno, 0, sizeof(sccno));
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(sccno[i]!=sccno[v])
Gp[sccno[i]].push_back(sccno[v]);
}
}
ans = 0;
memset(vis, 0, sizeof(vis));
for(i=scc_cnt;i>=1;i--)
{
if(vis[i]==0)
{
ans += cost[i];
Sech(i);
}
}
printf("Case #%lld: %lld\n", cas++, ans);
}
return 0;
}
地址:
点击打开链接