zoukankan      html  css  js  c++  java
  • Road Construction POJ

    传送门

    题意:给你n个点,r条无向边,问最少需要添加几条边使即使删除一条边,依旧能够从一点到达任意点

    题解:无向图强连通建边,只要将整个图建成一个边双连通图,那么删除任意一条边依旧还是能够从一点到达任意点

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <map>
    #include <queue>
    #include <vector>
    #include <cstring>
    #include <iomanip>
    #include <set>
    #define se second
    #define fi first
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define Pii pair<int,int>
    #define Pli pair<ll,int>
    #define ull unsigned long long
    #define pb push_back
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    const double Pi=3.14159265;
    const double e=2.71828182;
    const int N=3e3+5;
    const ull base=163;
    const ll INF=0x3f3f3f3f;
    using namespace std;
    int head[N],nx[N],to[N];
    int low[N],dfn[N];
    int tot=1;
    int vis[N];
    int sta[N],size=0,num=0;
    int com[N];
    void add(int u,int v){
        to[tot]=v;
        nx[tot]=head[u];
        head[u]=tot++;
    }
    void dfs(int x,int step,int pre){
        vis[x]=1;
        dfn[x]=low[x]=step;
        sta[size++]=x;
        int flag=0;
        for(int i=head[x];i;i=nx[i]){
            int v=to[i];
            if(v==pre&&!flag){
                flag=1;
                continue;
            }
            if(!vis[v])dfs(v,step+1,x);
            if(vis[v]==1)low[x]=min(low[x],low[v]);
        }
        if(dfn[x]==low[x]){
            int k;
            num++;
            do{
                k=sta[--size];
                com[k]=num;
            }while(k!=x);
        }
    }
    void tarjan(int n){
        for(int i=1;i<=n;i++)
            if(!vis[i])dfs(i,0,-1);
    }
    int in[N],out[N];
    void init(int n){
        tot=1;
        size=num=0;
        memset(head,0,sizeof(head));
        for(int i=1;i<=n;i++)vis[i]=in[i]=out[i]=0;
    }
    int main(){
        fio;
        //int oo=0;
        int n,r;
        while(cin>>n>>r){
            init(n);
            while(r--){
                int u,v;
                cin>>u>>v;
                add(u,v);
                add(v,u);
            }
            tarjan(n);
           // cout<<"Output for Sample Input "<<++oo<<endl;
            for(int u=1;u<=n;u++){
                for(int i=head[u];i;i=nx[i]){
                    int v=to[i];
                    if(com[v]==com[u])continue;
                    else{
                        in[com[v]]++;
                        out[com[u]]++;
                    }
                }
            }
            int ans=0;
            for(int i=1;i<num;i++){
                //cout<<in[i]<<"  "<<out[i]<<endl;
                if(in[i]==1&&out[i]==1)ans++;
            }
            cout<<(ans+1)/2<<endl;
        }
        return 0;
    }
  • 相关阅读:
    linux 经常使用配置
    Binder Proxy技术方案
    Android 通过系统使用NotificationListenerService 监听各种Notification的用法
    苟富贵勿相忘
    使用instantclient_11_2 和PL/SQL Developer工具包连接oracle 11g远程数据库
    JAVA: httpclient 具体解释——第五章;
    Unity入门
    向架构师进军---&gt;怎样编写软件架构文档
    SendMessage、PostMessage原理
    用GDB调试程序(一)
  • 原文地址:https://www.cnblogs.com/Mrleon/p/8711571.html
Copyright © 2011-2022 走看看