您的位置:首页 > 其它

【2016-CCPC-B】强连通分量,tarjan(Bomb,hdu 5934)

2016-10-29 21:54 507 查看
打了网上的重现赛,一直TLE+WA一度怀疑方法的问题,然后到最后也没找到,但发现了很多至关重要的小错误。

比如把边的序号当成点用,边的空间没开够等等等等。

赛后重写了,直接AC。

比赛很多时候就是这样,刚接触一道新的题目,先要思考一段时间,然后再编写程序,这些过程都是很生涩的,路途坑坑洼洼会有很多小障碍,而且没AC就得反复debug和修改,会把程序改得很乱,而且自己也会疲惫,然后往往就最后没过。只能说不够熟练,没有什么差一点点,只有付出的不够多,没有练到炉火纯青,顺手拈来的地步,而这是需要长时间大量的练习的。重写也是一个不错的选择,因为可能程序一开始就没写好,然后又被你改得乱七八糟,很多小细节是难以发现的。不如趁着思考了那么久,有着比较清晰的思路,去重写一份精炼的代码,不但可能会更注意细节,从而解决一些本就不应该出现的难以发现的bug,而且新的代码更加整洁,容易debug。

当时TLE就一直优化,连什么输入输出都优化了。。。然并卵,其实就是数组开的不够大之类的一些乱七八糟的错误吧,反正最后没找到。

代码

#include<bits/stdc++.h>
#define maxn 1010
#define INF 0X3F3F3F3F
using namespace std;

struct bomb
{
int x,y,r,c;
}B[maxn];
int N;

struct edge
{
int to,next;
}edges[maxn*maxn];
int tot,head[maxn];
void init()
{
tot=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v)
{
edges[tot].to=v;
edges[tot].next=head[u];
head[u]=tot++;
}

inline double dist(int i,int j)
{
double x=B[i].x-B[j].x;
double y=B[i].y-B[j].y;
return sqrt(x*x+y*y);
}
////////////////////////////
int dfn[maxn],low[maxn];
int cnt,num;
bool is[maxn];
int cost[maxn];
int belong[maxn];
stack<int>s;
void tarjan(int u)
{
dfn[u]=low[u]=++cnt;
is[u]=true;
s.push(u);
for(int i=head[u];i!=-1;i=edges[i].next)
{
int v=edges[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(is[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
num++;
while(s.top()!=u)
{
belong[s.top()]=num;
is[s.top()]=false;
cost[num]=min(cost[num],B[s.top()].c);
s.pop();
}
belong[s.top()]=num;
is[s.top()]=false;
cost[num]=min(cost[num],B[s.top()].c);
s.pop();
}
}
////////////////////////////
int id[maxn];

int solve()
{
memset(dfn,0,sizeof(dfn));
memset(id,0,sizeof(id));
memset(cost,INF,sizeof(cost));
cnt=num=0;
for(int i=1;i<=N;i++)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=N;i++)
for(int j=head[i];j!=-1;j=edges[j].next)
{
int v=edges[j].to;
int x=belong[i];
int y=belong[v];
if(x!=y) id[y]++;
}
int ans=0;
for(int i=1;i<=num;i++)
if(!id[i]) ans+=cost[i];
return ans;
}

int main()
{
int T;
scanf("%d",&T);
for(int t=1;t<=T;t++)
{
scanf("%d",&N);
for(int i=1;i<=N;i++)
scanf("%d %d %d %d",&B[i].x,&B[i].y,&B[i].r,&B[i].c);
init();
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
if(i!=j&&dist(i,j)<=B[i].r)
addedge(i,j);
printf("Case #%d: %d\n",t,solve());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: