您的位置:首页 > 大数据 > 人工智能

hdu 3394 Railway(Tarjan,点双连通分量)

2017-09-18 19:59 351 查看
看题意请移步:http://blog.csdn.net/kopyh/article/details/48345773

然后就上板子。

tle了一个多小时,找很多博客的代码对比,调试啊,最后发现是数组开小了,即使开小了,也比题目给的数据范围还是要大的。内存开销为啥是tle?

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 20010;
const int MAXM = 200100;
struct Edge
{
int to,next;
};
Edge edge[MAXM];
int head[MAXN];
int Low[MAXN],Dfn[MAXN],Stack[MAXN];
int tmp[MAXN];
int Index,top,Bridge,cc,res,tot;
bool ok[MAXN];

void init()
{
memset(Dfn,0,sizeof(Dfn));
memset(Low,0,sizeof(Low));
memset(head,-1,sizeof(head));
Index = top = tot = Bridge = res = 0;
}

void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}

void calc()
{
int sum = 0,u,v;
for(int i = 0; i < cc; ++i)
{
u = tmp[i];
for(int j = head[u]; ~j; j = edge[j].next)
{
v = edge[j].to;
if(ok[v]) sum++;
}
}
sum /= 2;//因为是无向图,所以要除以2,算出总边数
//如果边数大于点数,肯定有环
if(sum > cc)
res += sum;
}

void Tarjan(int u, int fa)
{
Low[u] = Dfn[u] = ++Index;
Stack[top++] = u;
for(int i = head[u]; ~i;  i = edge[i].next)
{
int v = edge[i].to;
if(!Dfn[v])
{
Tarjan(v,u);
Low[u] = min(Low[u],Low[v]);
if(Low[v] > Dfn[u]) ++Bridge;
if(Low[v] >= Dfn[u])
{
int vn;
cc = 0;//cc用于计数当前点连通分量中的点的个数
memset(ok,false,sizeof(ok));
do
{
vn = Stack[--top];
ok[vn] = true;//ok用于标记当前点连通分量中的点
tmp[cc++] = vn;
}while(vn != v);
tmp[cc++] = u;
ok[u] = true;
calc();
}
}
else if(v != fa)
Low[u] = min(Low[u],Dfn[v]);
}
}

void solve(int n)
{
for(int i = 1; i <= n; ++i)
if(!Dfn[i])
Tarjan(i,-1);
}
int main()
{
int n,m,u,v;
while(scanf("%d %d",&n,&m) && n+m)
{
init();
for(int i = 0; i < m; ++i)
{
scanf("%d %d",&u,&v);
addedge(u+1,v+1);
addedge(v+1,u+1);
}
solve(n);
printf("%d %d\n",Bridge,res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: