zoukankan      html  css  js  c++  java
  • HDU 4612 Warm up 连通图缩点

    题目大意:给出一个连通图,求再一个边后,剩余的最少桥数。

    题目思路:首先进行缩点得到重构后的图,求出重构后树的直径(通过两次BFS求出相距最远的两点间的距离),ans=重构图边数-树的直径

    //#pragma comment(linker, "/STACK:102400000,102400000")
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<math.h>
    #include<vector>
    #include<iostream>
    #include<queue>
    #include<algorithm>
    #define MAXSIZE 200005
    #define LL long long
    
    using namespace std;
    
    vector<vector<int> >G;
    vector<vector<int> >G2;
    int vis[MAXSIZE],low[MAXSIZE],dfn[MAXSIZE],pre[MAXSIZE],k,Time,n,m,ans,link;
    int dist[MAXSIZE],belong[MAXSIZE],step[MAXSIZE],Stuck[MAXSIZE],block;
    
    void Tarjan(int u,int fa)
    {
        low[u]=dfn[u]=++Time;
        pre[u]=fa;
        Stuck[k++]=u;
        int v,len=G[u].size(),op=0;
        for(int i=0;i<len;i++)
        {
            v=G[u][i];
            if(!op && v==fa)//去重边
            {
                op=1;
                continue;
            }
            if(!dfn[v])
            {
                Tarjan(v,u);
                low[u]=min(low[u],low[v]);
            }
            else
            {
                low[u]=min(low[u],dfn[v]);
            }
        }
        if(low[u]==dfn[u])
        {
            int temp;
            do{
                temp=Stuck[--k];
                belong[temp]=block;
            }while(temp!=u);
            block++;
        }
    }
    
    void Init()
    {
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        memset(pre,0,sizeof(pre));
        memset(belong,0,sizeof(belong));
        memset(Stuck,0,sizeof(Stuck));
        ans=0;
        Time=0;
        block=0;
        k=0;
        G.clear();
        G2.clear();
        G.resize(n+2);
        G2.resize(n+2);
    }
    
    int BFS(int s,int op)
    {
        int now,next;
        queue<int>Q;
        memset(step,-1,sizeof(step));
        step[s]=0;
        Q.push(s);
        while(!Q.empty())
        {
            now=Q.front();
            Q.pop();
            int len=G2[now].size();
            for(int i=0;i<len;i++)
            {
                next=G2[now][i];
                if(step[next]==-1)
                {
                    step[next]=step[now]+1;
                    Q.push(next);
                }
            }
        }
    
        if(op==0)
            return now;
        return step[now];
    }
    
    int main()
    {
        int a,b;
        while(scanf("%d%d",&n,&m),n+m)
        {
            Init();
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d",&a,&b);
                G[a].push_back(b);
                G[b].push_back(a);
            }
    
            for(int i=1;i<=n;i++)
            {
                if(!dfn[i])
                    Tarjan(i,i);
            }
    
            for(int i=1;i<=n;i++)
            {
                int fa=pre[i];
                if(belong[i] != belong[fa])
                {
                    G2[belong[i]].push_back(belong[fa]);
                    G2[belong[fa]].push_back(belong[i]);
                }
            }
            //两边BFS求出树的直径
            int s=BFS(0,0);
            int d=BFS(s,1);
            ans=block-d-1;// 重构后的图的边数等于点数-1,根据贪心策略再减去重构树的直径就是答案
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    去年一个百万级的小软件项目经验分享,20来个功能模块,项目不太好做有些棘手 zhuan zai
    软件架构师应该知道的97件事
    互联网创业需要哪些人? 留住人才,到一线去
    推荐:你可能需要的在线电子书 (转载)
    ios DOME(http://www.cocoachina.com/bbs/read.php?tid8101.html)
    在获得自信时常犯的三个错误 你的成功在于你每天养成的习惯
    Web开发性能优化总结 转载
    Android 移动平台概述
    互联网产品需求管理思考——统一需求管理
    Android 开发工具
  • 原文地址:https://www.cnblogs.com/alan-W/p/6535191.html
Copyright © 2011-2022 走看看