• 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;
    }
    
  • 相关阅读:
    html5 中的 css样式单 的 两种调用方式的区别
    互联网公司的相关人员及业务简介
    require.js 入门学习-备
    IOS修改webView背景透明以及IOS调用前台js的方法
    Javascript AMD模块化规范-备用
    Meta 的两个 相关属性
    <meta http-equiv="pragma" content="no-cache"/>
    css:中文词不断开,整体换行
    linux驱动开发---导出内核符号
    web html 防盗链
  • 原文地址:https://www.cnblogs.com/wlw-x/p/13329286.html
Copyright © 2020-2023  润新知