• Daliy Algorithm (并查集,链式前向星)-- day 96


    Nothing to fear


    种一棵树最好的时间是十年前,其次是现在!

    那些你早出晚归付出的刻苦努力,你不想训练,当你觉的太累了但还是要咬牙坚持的时候,那就是在追逐梦想,不要在意终点有什么,要享受路途的过程,或许你不能成就梦想,但一定会有更伟大的事情随之而来。 mamba out~

    2020.7.16


    人一我十,人十我百,追逐青春的梦想,怀着自信的心,永不言弃!

    lg- P1536 - 村村通

    并查集本集

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    
    using namespace std;
    
    const int N = 10010;
    int f[N] , vis[N];
    int n , m;
    int find(int k)
    {
    	if(k == f[k])return k;
    	else return f[k] = find(f[k]);
    }
    void Union(int a,int b)
    {
    	vis[a] = vis[b] = 1;
    	int A = find(a) , B = find(b);
    	f[A] = B;
    }
    void init()
    {
    	for(int i = 0;i < N ;i++)f[i] = i;
    	memset(vis , 0 ,sizeof vis);
    }
    int main()
    {	
    	while(1)
    	{
    		cin >> n;
    		if(n == 0)break;
    		cin >> m;init();
    		int a , b , cnt = 0;
    		for(int i = 0;i < m;i ++)
    		{
    			scanf("%d %d",&a , &b);
    			Union(a , b);
    		}
    		for(int i = 1;i <= n;i ++){
    			if(find(i) == i)cnt++;
    		}
    		cout << cnt - 1 << endl;
    	}	
    	return  0;
    }
    

    lg - P1892 [BOI2003]团伙

    分析

    既然连个人互为朋友那么必然可以属于一个团体之中,故此时需要合并,

    如果两个人互为敌人那么此时由于敌人的敌人依旧是我们的朋友我们可以遍历敌人的敌人,将其当作朋友进行合并,整个过程由并查集 + 链式前向星完成。并查集负责集合查找,链式前向星负责存储每个人的敌人

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    
    using namespace std;
    const int N = 1005;
    int f[N] , vis[N] , n , m;
    struct edge{
    	int w , to ,next;
    }e[N * N];
    int head[N] , tot;
    int find(int k)
    {
    	if(k == f[k])return k;
    	else return f[k] = find(f[k]);	
    }
    void Union(int a,int b)
    {
    	int A = find(a) , B = find(b);
    	f[A] = B;
    }
    void add(int a,int b)
    {
    	e[++tot].to = b;
    	e[tot].next = head[a];
    	head[a] = tot;
    }
    int main()
    {
    	cin >> n >> m;
    	for(int i = 1;i <= n;i ++)f[i] = i;
    	char ch;int a , b;
    	for(int i = 0;i < m;i ++)
    	{
    		cin >> ch >> a >> b;
    		if(ch == 'F')Union(a , b);
    		else{
    			add(a , b) , add(b , a);
    			// 寻找 b 的敌人作为a的朋友
    			for(int j = head[b] ; j ;j = e[j].next)
    			{
    				int y = e[j].to;
    				Union(a , y);
    			}
    			// 寻找 a 的敌人作为 b 的朋友
    			for(int j = head[a] ; j ;j = e[j].next)
    			{
    				int y = e[j].to;
    				Union(b , y);
    			}
    		}
    	}
    	int ans = 0;
    	for(int i = 1;i <= n;i ++)
    	{	
    		if(i == find(i))ans++;
    	}
    	cout << ans << endl;
    	return 0;
    }
    
  • 相关阅读:
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    Rng(求逆元)
    P1306 斐波那契公约数(ksm+结论)
    sort(桶排序+hash)
    牛客多校训练AFJ(签到)
    Educational Codeforces Round 68 (Rated for Div. 2)-D. 1-2-K Game
    Educational Codeforces Round 68 (Rated for Div. 2)-C-From S To T
    The Unique MST(最小生成树的唯一性判断)
    飞跃原野(三维bfs)
  • 原文地址:https://www.cnblogs.com/wlw-x/p/13329286.html
Copyright © 2020-2023  润新知