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

来源:互联网 发布:ubuntu下tar命令 编辑:程序博客网 时间:2024/05/18 09:19

看题意请移步: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;}