zoukankan      html  css  js  c++  java
  • 【PAT甲级训练】1013 Battle Over Cities(Tarjan求删去某个点后剩余的连通块个数,k个询问)

    【PAT甲级训练】1013 Battle Over Cities(Tarjan求删去某个点后剩余的连通块个数,k个询问)

    题目传送门

    题意

    看懂题意之后,发现是今年第一场小米邀请赛写过的一道题目,然后直接翻出了之前写的题解,粘过来了。

    这两道题的题意略有不同,但是本质上是一样的,小米那道题求的是删去某个点后剩余的连通块个数,而这道题是求删去该点后最少需要添加的边数使得剩下的图能够连通,这个边数=连通块个数-1

    在此就不再赘述,直接贴上小米邀请赛那一题的题解,再看看感觉只要理解Tarjan算法,理解起来还是蛮容易的。

    题解博客

    传送门

    代码

    /****************************
    * Author : W.A.R            *
    * Date : 2020-10-11-17:19   *
    ****************************/
    /*
    */
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<stack>
    #include<string>
    #include<set>
    #define IOS ios::sync_with_stdio(false)
    #define show(x) std:: cerr << #x << " = " << x << std::endl;
    #define mem(a,x) memset(a,x,sizeof(a))
    #define Rint register int
    using namespace std;
    typedef long long ll;
    const int maxn=1e6+10;
    const int maxm=2e6+10;
    const ll mod=1e9+7;
    const double PI=acos(-1.0);
    const double eps=1e-7;
    ll qpow(ll a,ll n){a%=mod;ll ans=1;while(n){if(n%2)ans=ans*a%mod;n/=2;a=a*a%mod;}return ans;}
    int dcmp(double x){if(fabs(x)<eps)return 0;if(x>0)return 1;return -1;}
    struct Edge{int to,nxt;}e[maxn*2];
    int ques[maxn],head[maxn],dfn[maxn],low[maxn],ans[maxn],ct,cnt,now;
    void addE(int u,int v){e[++ct].to=v;e[ct].nxt=head[u];head[u]=ct;}
    void Tarjan(int u){
        dfn[u]=low[u]=++cnt;
        ans[u]=u!=now;
        for(int i=head[u];i;i=e[i].nxt){
            int v=e[i].to;
            if(!dfn[v]){
                Tarjan(v);
                low[u]=min(low[u],low[v]);
                ans[u]+=(dfn[u]<=low[v]);
            }
            else low[u]=min(low[u],dfn[v]);
        }
    }
    
    int main(){
        int n,m,k;scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=m;i++){
            int u,v;scanf("%d%d",&u,&v);
            addE(u,v);addE(v,u);
        }
        for(int i=1;i<=k;i++)scanf("%d",&ques[i]);
    	int C=0;
        for(int i=1;i<=n;i++)if(!dfn[i])now=i,Tarjan(i),C++;
        //for(int i=1;i<=n;i++)printf("%d%c",C+ans[i]-1,i==n?'
    ':' ');
        for(int i=1;i<=k;i++)printf("%d
    ",C+ans[ques[i]]-2);
    	return 0;
    }
    
  • 相关阅读:
    在Eclipse中使用Checkstyle 检查Java代码规范
    文件缓存法的具体实现
    hdu 4454 Stealing a Cake
    uva 11922
    uva 11020
    uva 12206
    uva 11107
    uva 11796
    uva 11178
    uva 11437
  • 原文地址:https://www.cnblogs.com/wuanran/p/14467431.html
Copyright © 2011-2022 走看看