zoukankan      html  css  js  c++  java
  • cf1276B

    题意简述:给出无向图,会有重边,然后给你两个点a,b,让你计算有多少点对(x,y)满足从x到y的所有路径都经过a和b

    题解:先从a,b两点出发进行dfs,dfs的过程中不能经过a,b两点(除了开始)

    所有的点分为了三类,第一类是a能到但是b到不了,第二类是b能到但是a到不了,第三类是a,b都能到

    首先每一类点的内部之间的点对对答案没有贡献,因为他们之间到达可以只经过a,b其中一个点

    所以只需要考虑不同类之间的点对答案的贡献

    第一类和第三类对答案没有贡献,因为对于点对x,y,x可以先a再到y,而不需要今过b点,因此没有贡献

    同理第二类对第三类也没有贡献

    第一类和第二类,他们相通必须经过a,b两点

    因此答案就是第一类的点数×第二类的点数

    const int maxn=2e5+5;
    const int maxm=1e6+5;
    const int inf=1e9;
    
    
    int n,m,a,b;
    
    int head[maxn],ver[maxm],nex[maxm],tot;
    
    void inline AddEdge(int x,int y){
    	ver[++tot]=y,nex[tot]=head[x],head[x]=tot;
    } 
    
    bool vis[maxn];
    
    int cnt[maxn];
    
    void dfs(int x,int f){
    	vis[x]=1;
    	cnt[x]+=f;
    	for(int i=head[x];i;i=nex[i]){
    		int y=ver[i];
    		if(!vis[y] && y!=a && y!=b) {
    			dfs(y,f);
    		}
    	}
    }
    
    void solve(){
    	cin>>n>>m>>a>>b;
    	tot=0;
    	for(int i=1;i<=n;i++)
    		head[i]=0;
    	for(int i=0;i<m;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		AddEdge(x,y);
    		AddEdge(y,x);
    	}
    	for(int i=1;i<=n;i++)
    		vis[i]=cnt[i]=0;
    	dfs(a,1);
    	for(int i=1;i<=n;i++)
    		vis[i]=0;
    	dfs(b,2);
    	ll s1=0,s2=0;
    	for(int i=1;i<=n;i++){
    	//	cout<<cnt[i]<<endl;
    		if(i!=a && i!=b) {
    			if(cnt[i]==1) s1++;
    			else if(cnt[i]==2) s2++;
    		}
    	}
    	//cout<<s1<<' '<<s2<<endl;
    	printf("%lld
    ",s1*s2);
    }
    int main(){
    	int t;
    	cin>>t;
    	while(t--)
    		solve();
    }
    

      

  • 相关阅读:
    鹅厂女专家:用“爱折腾”实现跨界之美
    基于腾讯云的视频聊天研究
    iOS微信内存监控
    2017年数据库技术盘点
    如何做好游戏内实时语音体验
    腾讯云微计算实践:从Serverless说起,谈谈边缘计算的未来
    使用腾讯云“自定义监控”监控GPU使用率
    如何在Python中从零开始实现随机森林
    DataGridView 设置某个列为只能为数字
    Ieditor
  • 原文地址:https://www.cnblogs.com/033000-/p/12328311.html
Copyright © 2011-2022 走看看