zoukankan      html  css  js  c++  java
  • HDU 4612 Warm up

    给出一个无向图,你可以加一条边,使得加上边之后的图割边数量最少。

    方法:每个边双连通分量缩点,形成一个树,树上的每条边都是割边,割边数量为S1;

    接下来只要算出树上最长路径(树的直径)就可以了,最长路径两段连线,路径上的割边都不可能再成为割边了,记最长路径长度为S2;

    Ans=S1-S2;

    第一步可以用Tarjan算法

    树的直径可以这样求:先随便找一个点P,DFS一下,找到与P距离最远的那个点St;然后从St出发,再进行一次DFS,与St相距最远的那个点的距离就是树的直径。

    这个题目搞了一天,一直是MLE,后来把vector改成数组就AC了.....

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    const int maxn=200000+10;
    const int Maxn=2*1000000+10;
    const int INF=0x7FFFFFFF;
    int low[maxn];
    int dfn[maxn];
    int U[Maxn],V[Maxn];
    int flag[Maxn];
    int head[maxn];
    
    struct Edge
    {
        int to,ans;
        int next;
    } edge[Maxn];
    
    int N,M;
    int tmpdfn;
    int tot;
    int son;
    int Start,End;
    int TxT[maxn];
    int ShuYu[maxn];
    int SS,Ans,JiLu,MA,St;
    vector<int>Tree[maxn];
    int Biao[maxn];
    
    void init()
    {
    
        for(int i=0; i<=N; i++) Tree[i].clear();
    
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        memset(flag,0,sizeof(flag));
        memset(TxT,0,sizeof(TxT));
        memset(ShuYu,0,sizeof ShuYu);
        memset(Biao,0,sizeof Biao);
        memset(head,-1,sizeof head);
        low[1]=dfn[1]=1;
        tmpdfn=0;
        tot=0;
        son=0;
        SS=0;
    }
    
    void AddEdge(int u,int v)
    {
        edge[tot].to=v;
        edge[tot].next=head[u];
        edge[tot].ans=0;
        head[u]=tot++;
    
        edge[tot].to=u;
        edge[tot].next=head[v];
        edge[tot].ans=0;
        head[v]=tot++;
    }
    
    int Tarjan(int u,int id)
    {
        tmpdfn++;
        int lowu=dfn[u]=tmpdfn;
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            int B=i;
            if(!dfn[edge[B].to])
            {
                int lowv=Tarjan(edge[B].to,B);
                lowu=min(lowu,lowv);
                if(lowv>=dfn[u])
                {
                    if(u==1) son++;
                    if(lowv>dfn[u])
                    {
                        edge[B].ans=1;
                        edge[B^1].ans=1;
                    }
                }
            }
            else if(dfn[edge[B].to])
            {
                if(B/2==id/2) continue;
                lowu=min(lowu,dfn[edge[B].to]);
            }
        }
        low[u]=lowu;
        return lowu;
    }
    
    void Dfs(int x,int y)
    {
        int XZ=0;
        for(int i = head[x]; i != -1; i = edge[i].next)
        {
            int B=i;
            if(!flag[B/2]&&!TxT[edge[B].to])
            {
                XZ=1;
                flag[B/2]=1;
                TxT[edge[B].to]=1;
                ShuYu[x]=SS;
                ShuYu[edge[B].to]=SS;
                Dfs(edge[B].to,y+1);
            }
        }
        if(!XZ&&!y) ShuYu[x]=SS;
    }
    
    void Slove()
    {
        for(int i=0; i<2*M; i++)
            if(edge[i].ans)
                flag[i/2]=1;
    
        for(int i=Start; i<=End; i++)
        {
            if(!TxT[i])
            {
                TxT[i]=1;
                SS++;
                Dfs(i,0);
            }
        }
    }
    
    void dfs1(int now,int len)
    {
        if(len>MA)
        {
            MA=len;
            St=now;
        }
        Biao[now]=1;
        for(int i=0; i<Tree[now].size(); i++)
            if(Biao[Tree[now][i]]==0)
                dfs1(Tree[now][i],len+1);
    }
    
    void dfs2(int now,int len)
    {
        if(len>MA) MA=len;
        Biao[now]=1;
        for(int i=0; i<Tree[now].size(); i++)
            if(Biao[Tree[now][i]]==0)
                dfs2(Tree[now][i],len+1);
    }
    
    int main()
    {
        while(~scanf("%d%d",&N,&M))
        {
            if(N==0&&M==0) break;
            init();
            for(int i=0; i<M; i++)
            {
                scanf("%d%d",&U[i],&V[i]);
                AddEdge(U[i],V[i]);
            }
    
            Start=1;
            End=N;
            Tarjan(1,-1);
            Slove();
            for(int i=0; i<M; i++)
            {
                if(ShuYu[U[i]]==ShuYu[V[i]]) continue;
                Tree[ShuYu[U[i]]].push_back(ShuYu[V[i]]);
                Tree[ShuYu[V[i]]].push_back(ShuYu[U[i]]);
            }
            MA=-INF;
            dfs1(1,0);
            memset(Biao,0,sizeof Biao);
            MA=-INF;
            dfs2(St,0);
            Ans=MA;
    
            printf("%d
    ",SS-1-Ans);
        }
        return 0;
    }
  • 相关阅读:
    ArcEngine9.3没有原生支持64位,而是以32位兼容方式运行
    记一次IIS应用程序域崩溃的原因
    切换添加[置顶] Behaviors扩展根据Pivot的item自动切换AppBar
    参数类型11g_job执行带参数的procedure
    元素返回[Python]python算法入门 栈(stack)
    模型案例复杂性思考
    执行目录glassfish不能远程登录问题
    文件目录IBM的LPI复习资料之LPI101Topic103 :GNU和Unix命令(3)文件和目录管理
    企业网站[正能量系列]失业的程序员(一)
    缓冲区方法你有被stringstream坑过吗?
  • 原文地址:https://www.cnblogs.com/zufezzt/p/4764748.html
Copyright © 2011-2022 走看看