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

    http://acm.hdu.edu.cn/showproblem.php?pid=4612

    将原图进行缩点 变成一个树

    树上每条边都是一个桥 然后加一条边要加在树的直径两端才最优

    代码:

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<cmath>
    #include<set>
    #include<map>
    #include<stack>
    #include<vector>
    #include<algorithm>
    #include<queue>
    #include<bitset>
    #include<deque>
    #include<numeric>
    
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    
    using namespace std;
    
    
    typedef long long ll;
    typedef unsigned int uint;
    typedef pair<int,int> pp;
    const double eps=1e-9;
    const int INF=0x3f3f3f3f;
    const ll MOD=1000000007;
    const int N=210000;
    const int M=2100000;
    int head1[N],I1;
    int head2[N],I2;
    struct node
    {
        int j,next;
    }edge1[M],edge2[M];
    bool ev[M];
    int dist[N];
    int low[N],dfn[N],f[N],deep;
    bool in[N],visited[N];
    int num[N],sel[N];
    stack<int>st;
    queue<int>qt;
    vector<int>vt[N];
    void add1(int i,int j)
    {
        edge1[I1].j=j;
        edge1[I1].next=head1[i];
        head1[i]=I1++;
    }
    void add2(int i,int j)
    {
        edge2[I2].j=j;
        edge2[I2].next=head2[i];
        head2[i]=I2++;
    }
    void tarjan(int x)//将环缩点
    {
        visited[x]=true;
        in[x]=true;
        st.push(x);
        low[x]=dfn[x]=deep++;
        for(int t=head1[x];t!=-1;t=edge1[t].next)
        if(!ev[t])
        {
            ev[t]=true;
            ev[t^1]=true;
            int j=edge1[t].j;
            if(visited[j]==false)
            {
                tarjan(j);
                low[x]=min(low[x],low[j]);
    
            }else if(in[j]==true)
            {
                low[x]=min(low[x],dfn[j]);
            }
        }
        if(low[x]==dfn[x])
        {
            while(st.top()!=x)
            {
                int k=st.top(); st.pop();
                in[k]=false;
                f[k]=x;
                vt[x].push_back(k);
            }
            int k=st.top(); st.pop();
            in[k]=false;
            f[k]=x;
        }
    }
    void buildNewGraph(int k)
    {
        memset(head2,-1,sizeof(head2));I2=0;
        for(int i=0;i<k;++i)
        {
            for(int t=head1[i];t!=-1;t=edge1[t].next)
            {
                int j=edge1[t].j;
                if(f[i]!=f[j])
                {
                    add2(f[j],f[i]);
                    ++num[f[i]];
                }
            }
        }
    }
    void init(int n,int m)
    {
        memset(head1,-1,sizeof(head1));
        I1=0;
        while(m--)
        {
            int l,r;
            scanf("%d %d",&l,&r);
            --l;--r;
            add1(l,r);
            add1(r,l);
        }
    }
    int bfs(int x1,int n)
    {
        memset(dist,-1,sizeof(dist));
        queue<int>qt;
        dist[x1]=0;
        qt.push(x1);
        while(!qt.empty())
        {
            int x=qt.front();
            qt.pop();
            for(int t=head2[x];t!=-1;t=edge2[t].next)
            {
                int j=edge2[t].j;
                if(dist[j]==-1)
                {
                    dist[j]=dist[x]+1;
                    qt.push(j);
                }
            }
        }
        int k=0;
        for(int i=0;i<n;++i)
        if(dist[i]>dist[k])
        k=i;
        return k;
    }
    int solve(int n)
    {
        int s=0,sum=0;
        for(int i=0;i<n;++i)
        if(f[i]==i)
        {s=i;++sum;}
        int k=bfs(s,n);
        k=bfs(k,n);
        return (sum-1-dist[k]);
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int n,m;
        while(scanf("%d %d",&n,&m)!=EOF)
        {
            if(n==0&&m==0)
            break;
            init(n,m);
            while(!st.empty()) st.pop();
            for(int i=0;i<n;++i)
            {vt[i].clear();f[i]=i;}
            memset(in,false,sizeof(in));
            memset(visited,false,sizeof(visited));
            memset(ev,false,sizeof(ev));
            deep=0;
            for(int i=0;i<n;++i)
            if(!visited[i])
            tarjan(i);
            buildNewGraph(n);
            printf("%d
    ",solve(n));
        }
        return 0;
    }
    
  • 相关阅读:
    java模糊关键字查询
    Asp.Net MVC 扩展 Html.ImageFor 方法详解
    mvc下ajax请求遇到session超时简单处理方式
    8天学通MongoDB——第一天 基础入门
    MVC5中使用jQuery Post 二维数组和一维数组到Action
    构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(33)-数据验证共享
    构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(31)-MVC使用RDL报表
    构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(30)-本地化(多语言)
    JQuery文件上传插件ajaxFileUpload在Asp.net MVC中的使用
    MVC 5 + EF6 入门完整教程14 -- 动态生成面包屑导航
  • 原文地址:https://www.cnblogs.com/liulangye/p/3215333.html
Copyright © 2011-2022 走看看