zoukankan      html  css  js  c++  java
  • P7323[WC2021]括号路径【并查集,启发式合并】

    正题

    题目链接:https://www.luogu.com.cn/problem/P7323


    题目大意

    给出\(n\)个点的一张有向图。每个边\((u,v,w)\)表示\(u->v\)有一个类型\(w\)的左括号边,\(v->u\)有一个类型\(w\)的右括号边。

    求图中有多少点对满足它们之间有一条合法的括号序列路径

    \(1\leq n\leq 3\times 10^5,1\leq m\leq 6\times 10^5,1\leq k\leq n\)


    解题思路

    一个显然的结论是如果两个点之间有合法路径那么连一条边的话,那么最后出来的是一个团。

    因为\(f(u,v)=1\Rightarrow f(v,u)=1\)(路径翻转),\(f(u,v)=f(v,z)=1\Rightarrow f(u,z)=1\)(路径拼接)。

    考虑怎么求出这些团。假设我们现在有一个团\(x\),它连接向团外有两条类型一样的边,那么就代表我们可以把这两条边连接的节点(或者团)合并入这个团中。

    然后合并的时候我们因为又要处理类型一样的边,所以我们用启发式合并枚举小的那个暴力丢进大的里面就好了。

    时间复杂度\(O(n\log^2 n)\),用线段树合并可以做到\(O(n\log n)\)(也许?


    code

    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<map>
    #define mp(x,y) make_pair(x,y)
    using namespace std;
    const int N=3e5+10;
    int n,m,k,fa[N],cnt[N];
    long long ans;
    queue<pair<int,int> >q;
    map<int,int> G[N];
    int find(int x)
    {return (fa[x]==x)?x:(fa[x]=find(fa[x]));}
    map<int,int>::iterator it;
    int main()
    {
    	scanf("%d%d%d",&n,&m,&k);
    	for(int i=1;i<=m;i++){
    		int x,y,w;
    		scanf("%d%d%d",&x,&y,&w);
    		swap(x,y);
    		if(G[x][w])q.push(mp(G[x][w],y));
    		else G[x][w]=y;
    	}
    	for(int i=1;i<=n;i++)fa[i]=i;
    	while(!q.empty()){
    		int x=q.front().first,y=q.front().second;
    		x=find(x);y=find(y);q.pop();
    		if(x==y)continue;
    		if(G[x].size()<G[y].size())swap(x,y);
    		for(it=G[y].begin();it!=G[y].end();it++){
    			int w=it->first,z=it->second;
    			if(G[x][w])q.push(mp(G[x][w],z));
    			else G[x][w]=z;
    		}
    		fa[y]=x;
    	}
    	for(int i=1;i<=n;i++)cnt[find(i)]++;
    	for(int i=1;i<=n;i++)ans+=1ll*cnt[i]*(cnt[i]-1)/2ll;
    	printf("%lld\n",ans);
    	return 0;
    }
    
  • 相关阅读:
    js常用方法收集
    Jquery的常用使用方法
    jQuery css()选择器使用说明
    解决IE6,边框问题
    HTML问题集锦及笔记
    我的第一个chrome扩展(3)——继续读样例
    我的第一个chrome扩展(0)——目标
    我的第一个chrome扩展(2)——基本知识
    我的第一个chrome扩展(1)——读样例,实现时钟
    2の奇妙用法
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/14600494.html
Copyright © 2011-2022 走看看