贝壳找房魔法师顾问[并查集+DAG判断]
题目链接【https://nanti.jisuanke.com/t/27647】
//计蒜客2018复赛D题,想简单了。
题解:
题目是中文的,不再赘述。
题解:
分为三种情况:1、两个字符串都不能变:这种情况最简单,直接暴力判断两个支付穿是否相同即可。
2、两个字符串都能变:把上下对应位置不同的点连无向边(因为都可以改变),建立了一个深林,这里用并查集实现,顺便维护每个联块的大小,对于每个联通块来说,要把这些点都变成一样的,最少要变换(size-1)次,即选出一个点,把其他的点都变成被选中的点。
3、一个能变,一个不能变:这种情况最复杂。同第二种情况,这里需要建图,建立单向边,(只能由V变成C),对于每一个联通块,我们判断该联通块是不是DAG,如果是,那么只需要改变(size-1)次就行了。如果不是DAG,那么联通块中存在环,那么最少要变(size)次,只需要把这些点连接成有向环就可以了,保证了两两可以互达。
只是思路、具体细节和原因需要自己思考。欢迎斧正。QQ2421780543。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + ;
LL a[maxn], b[maxn];
char s[], t[];
//-----------------------并查集
int fa[maxn], val[maxn];
void init()
{
for(int i = ; i <= ; i++)
fa[i] = i, val[i] = ;
}
int Find(int u)
{
if(fa[u] == u)
return u;
return fa[u] = Find(fa[u]);
}
void Unit(int u, int v)
{
int x = Find(u);
int y = Find(v);
if(x != y)
{
fa[x] = y;
val[y] += val[x];
val[x] = ;
}
}
//-------------------------EDGE
int rd[maxn], vis[maxn], cnt = ;;
vector<int>vt[maxn];
map<int, int>mp;
queue<int>que;
struct Edge
{
int to, next;
Edge(int to = , int next = ): to(to), next(next) {}
} E[maxn * ];
int head[maxn], tot;
void Init_Edge()
{
for(int i = ; i <= ; i++)
head[i] = -;
tot = ;
}
void Add_Edge(int u, int v)
{
E[tot] = Edge(v, head[u]);
head[u] = tot++;
}
//--------------------------主函数
int main ()
{
int n, fg1 = , fg2 = ;
scanf("%d", &n); scanf("%s", s);
for(int i = ; i <= n; i++)
scanf("%lld", &a[i]);
scanf("%s", t);
for(int i = ; i <= n; i++)
scanf("%lld", &b[i]); if(s[] == 'V')
fg1 = ;
if(t[] == 'V')
fg2 = ; if((!fg1) && (!fg2))//都不能更改
{
bool ans = true;
for(int i = ; i <= n && ans; i++)
if(a[i] != b[i])
ans = false;
if(ans)
printf("0\n");
else
printf("-1\n");
}
else if(fg1 && fg2)//都可以更改
{
init();
for(int i = ; i <= n; i++)
{
if(a[i] != b[i])
Unit(a[i], b[i]);
}
int num = ;
for(int i = ; i <= ; i++)
{
Find(i);
if(fa[i] == i)
num += val[i] - ;
}
printf("%d\n", num); }
else //只能改一个
{
init();
Init_Edge();
for(int i = ; i <= n; i++)
if(a[i] != b[i])
{
Unit(a[i], b[i]);
Add_Edge(a[i], b[i]);
rd[b[i]] ++;
vis[a[i]] = vis[b[i]] = ;
}
for(int i = ; i <= ; i++)//提取联通块
{
if(vis[i])
{
int t = Find(i);
if(mp[t])
{
int tmp = mp[t];
vt[tmp].push_back(i);
}
else
{
mp[t] = ++cnt;
vt[cnt].push_back(i);
}
}
}
int num = ;
for(int i = ; i <= cnt; i++)//拓扑排序,判断DAG
{
int len = vt[i].size();
for(int j = ; j < len; j++)
{
int tmp = vt[i][j];
if(rd[tmp] == )
que.push(tmp);
}
int tmp = ;
while(!que.empty())
{
int u = que.front();
que.pop();
tmp++;
for(int j = head[u]; j != -; j = E[j].next)
{
int v = E[j].to;
rd[v]--;
if(rd[v] == )
que.push(v);
}
}
if(tmp == len)
num += len - ;
else
num += len;
}
printf("%d\n", num);
}
return ;
}
贝壳找房魔法师顾问[并查集+DAG判断]的更多相关文章
- 2018 计蒜之道复赛 贝壳找房魔法师顾问(并查集+dfs判环)
贝壳找房在遥远的传奇境外,找到了一个强大的魔法师顾问.他有 22 串数量相同的法力水晶,每个法力水晶可能有不同的颜色.为了方便起见,可以将每串法力水晶视为一个长度不大于 10^5105,字符集不大于 ...
- HDU-1232 畅通工程 (并查集、判断图中树的棵数)
Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连,只要互相 ...
- HDU-1272 小希的迷宫 (并查集、判断图是否为树)
Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就 ...
- HDOJ1272(并查集,判断是否为树)
0 0 Yes 1 1 0 0 Yes 1 2 2 1 0 0 No //自回路不算一条边的! 居然有 0 0 这样的测试数据 #include<iostream> #include< ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- Luogu P3367 【模板】并查集
题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入输出格式 输入格式: 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数Zi.Xi.Yi 当Zi=1 ...
- Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) Problem C (Codeforces 828C) - 链表 - 并查集
Ivan had string s consisting of small English letters. However, his friend Julia decided to make fun ...
- POJ:1182 食物链(带权并查集)
http://poj.org/problem?id=1182 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1 ...
- 天梯赛 L2-013. (并查集) 红色警报
题目链接 题目描述 战争中保持各个城市间的连通性非常重要.本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报.注意:若该国本来就不完全连通,是分裂的k个区域 ...
随机推荐
- insserv: Script <name> is broken: incomplete LSB comment.
insserv: Script <name> is broken: incomplete LSB comment. insserv: missing `Required-Start:' e ...
- [Apio2012]dispatching 左偏树做法
http://codevs.cn/problem/1763/ 维护子树大根堆,当子树薪水和>m时,删除最贵的点 #include<cstdio> #include<iostre ...
- kubeadm部署Kubernetes集群
Preface 通过kubeadm管理工具部署Kubernetes集群,相对离线包的二进制部署集群方式而言,更为简单与便捷.以下为个人学习总结: 两者区别在于前者部署方式使得大部分集群组件(Kube- ...
- Splay模板讲解及一些题目
普通平衡树模板以及文艺平衡树模板链接. 简介 平衡二叉树(Balanced Binary Tree)具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二 ...
- [转载]详解主流浏览器多进程架构:Chrome、IE
http://www.cnbeta.com/articles/109595.htm 随着Web浏览器重要性的日益突出,恶意软件.木马.间谍软件等网络攻击也呈现逐渐的上升.而面对 如此众多的潜在威胁,为 ...
- 20155232 2016-2017-3 《Java程序设计》第8周学习总结
20155232 2016-2017-3 <Java程序设计>第8周学习总结 教材学习内容总结 第十四章NIO与NIO2 NIO使用频道来衔接数据结点,在处理数据时,NIO可以让你设定缓冲 ...
- 第10月第10天 git
1. 已经用 git commit 提交了代码. 此命令可以用来回退到任意版本:git reset --hard commitid https://www.cnblogs.com/qufanblo ...
- 由一篇吐槽对String空字符串判断的文章所引发的碎碎念
一.起因 最近有篇关于String空字符串判断的文章火了,老是看到这篇文章,既然如此我也只好认真看了下:程序员晒出一段代码引来无数网友狂喷!网友:你就活该当码农! 我也觉得这段代码写的不怎么的,首先程 ...
- Linux下可以使用ps命令来查看Oracle相关的进程
Linux下可以使用ps命令来查看Oracle相关的进程 Oracle Listener 这个命令会列出Oracle Net Listener的进程 [oracle@ www.linuxidc.com ...
- 洛谷 P5206: bzoj 5475: LOJ 2983: [WC2019] 数树
一道技巧性非常强的计数题,历年WC出得最好(同时可能是比较简单)的题目之一. 题目传送门:洛谷P5206. 题意简述: 给定 \(n, y\). 一张图有 \(|V| = n\) 个点.对于两棵树 \ ...