UVA 10158 并查集的经典应用
这个题目一看就是用并查集,有N个国家代表,在M行给出两两之间的关系,敌人或者朋友,(当然如果该关系跟已知关系冲突,则输出-1)
关系的几个约束条件时这样的
在朋友方面,朋友的朋友就是自己的朋友,这个就是并查集。
在敌人方面,
x和其所有朋友的敌人都是敌人。
x和其所有敌人的敌人都是朋友。
主要是这个敌人的状态不太好表示,不是一个并查集能做到的,我一开始犯糊涂,直接用个图把x的敌人存贮起来,但是因为每次交新的朋友或者敌人,就要搜索全图,而且要把自己的敌人圈更新到整个朋友圈,这样不仅难以实现,复杂度也是相当高
后来就发现一个神级方法,简单易用,即,每个国家都有自己的对立面(实际上不存在),作用是这样的,x的对立面为x+n,如果某国y要跟x做敌人,则,y就和x+n放在同一个并查集里。这样就不会跟本体有影响,但是又达到了结仇的目的。
这样的话,x和y结盟,则 x和y属于一个集合, x+n和y+n属于同一集合(把对立面也绑定,再结仇的时候无论是和x还是y结仇,都会同时跟两个国家结仇,这样就其实就达到了第一个条件)。
如果x和y结仇,则x和y+n在同一集合,同时,y和x+n在同一集合。(结仇之后,如果两个国家有共同的仇人,则通过并查集操作,必定到了同一个集合,这样就满足了仇人的仇人是朋友的条件)
这样判断前后是否冲突,也可以根据这几个条件,如果当前操作是结仇,则一旦发现x和y已经是一个集合(或者他们的对立面),则冲突
如果当前是结盟,一旦发现x和y+n是一个集合 或者 y和x+n是一个集合,则冲突。
#include <iostream>
#include <cstdio>
#define N 10010
using namespace std;
int f[*N];
int n,x,y,c;
void init()
{
for (int i=;i<=*n;i++){
f[i]=i;
}
}
int findset(int a)
{
if (a!=f[a])
f[a]=findset(f[a]);
return f[a];
} void solve()
{
int r1,r2,r3,r4;
r1=findset(x);
r2=findset(y);
r3=findset(x+n);
r4=findset(y+n);
//cout<<r1<<" "<<r2<<" "<<r3<<" "<<r4<<endl;
if (c==)
{
if (r1==r4){
puts("-1");
return;
}
f[r1]=r2;
f[r3]=r4;
return;
}
if (c==)
{
if (r1==r2)
{
puts("-1");
return;
}
f[r1]=r4;
f[r2]=r3;
return;
}
if (c==)
{
if (r1==r2)
puts("");
else
puts("");
}
if(c==)
{
if (r1==r4)
puts("");
else
puts("");
} }
int main()
{
int i,j;
scanf("%d",&n);
init();
while (scanf("%d%d%d",&c,&x,&y))
{
if (!c) break;
solve();
}
return ;
}
UVA 10158 并查集的经典应用的更多相关文章
- poj 1611:The Suspects(并查集,经典题)
The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 21472 Accepted: 10393 De ...
- UVa 10129 (并查集 + 欧拉路径) Play on Words
题意: 有n个由小写字母的单词,要求判断是否存在某种排列使得相邻的两个单词,前一个单词末字母与后一个单词首字母相同. 分析: 将单词的两个字母看做节点,则一个单词可以看做一条有向边.那么题中所求的排列 ...
- UVa 11987 并查集 Almost Union-Find
原文戳这 与以往的并查集不同,这次需要一个删除操作.如果是叶子节点还好,直接修改父亲指针就好. 但是如果要是移动根节点,指向它的所有子节点也会跟着变化. 所以要增加一个永远不会被修改的虚拟根节点,这样 ...
- POJ 1182食物链(分集合以及加权两种解法) 种类并查集的经典
题目链接:http://icpc.njust.edu.cn/Problem/Pku/1182/ 题意:给出动物之间的关系,有几种询问方式,问是真话还是假话. 定义三种偏移关系: x->y 偏移量 ...
- leetcode 76 dp& 强连通分量&并查集经典操作
800. Similar RGB Color class Solution { int getn(int k){ return (k+8)/17; } string strd(int k){ char ...
- ACM/ICPC 之 并查集-食物链(POJ1182)
并查集的经典题型,POJ上题目还是中文= =,一般看到中文题都会感觉不太简单,这道题的数学归纳用得比较多,可以简化代码,挺有意思的. 同类型的题目还有POJ1703,比这个要简单,想了解并查集基本介绍 ...
- (中等) POJ 1703 Find them, Catch them,带权并查集。
Description The police office in Tadu City decides to say ends to the chaos, as launch actions to ro ...
- 并查集--CSUOJ 1601 War
并查集的经典题目: CSUOJ 1601: War Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 247 Solved: 70[Submit][Sta ...
- 【带权并查集】poj1182 食物链
带权并查集,或者叫做种类并查集,经典题. http://blog.csdn.net/shuangde800/article/details/7974668 这份代码感觉是坠吼的. 我的代码是暴力分类讨 ...
随机推荐
- doc转docx
# -*- coding: utf-8-*- import win32com from win32com.client import Dispatch w = win32com.client.Disp ...
- js ajax跨域调用
正常使用ajax调用java.com $.ajax({ type: 'get', url: 'http://www.java.com/custinfo?id=888', dataType: 'json ...
- 《Python爬虫技术:深入理解原理、技术与开发》已经出版,送Python基础视频课程
好消息,<Python爬虫技术:深入理解原理.技术与开发>已经出版!!! JetBrains官方推荐图书!JetBrains官大中华区市场部经理赵磊作序!送Python基础视频课程!J ...
- python画一只佩奇
用python画一只佩奇 from turtle import* def nose(x,y):#鼻子 penup()#提起笔 goto(x,y)#定位 pendown()#落笔,开始画 sethead ...
- C# Stream篇(四) -- FileStream
FileStream 目录: 如何去理解FileStream? FileStream的重要性 FileStream常用构造函数(重要) 非托管参数SafeFileHandle简单介绍 FileStre ...
- 公告上下滚动基于Jquery
前提 需要引入jquery 如果你用的单位不是px 修改的同时红色部分需保持一致 <!DOCTYPE html> <html> <head> <meta ...
- 【golang】golang的一些知识要点
特殊常量iota: 1.iota的值在遇到const关键字时将被重置为0 2.const中每新增一行常量声明将使iota计数一次,也就是自动加一. 3.iota只能在常量定义中使用. iota常见使用 ...
- Java算法练习——盛最多水的容器
题目链接 题目描述 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) ...
- 洛谷 P2370 yyy2015c01的U盘
题目传送门 解题思路: 先将每个文件按照占空间从小到大排序,然后跑背包,当到了某一个文件时,价值够了,那么当前文件的体积就是答案. 其实本题是可以二分答案的,但是写挂了... AC代码: #inclu ...
- CSS - input 美化
input{ padding: 20px; width: 100%; height: 5vh; margin-bottom: 2vh; border-radius: 10vw; border: 0; ...