BZOJ1077 并查集
1077: [SCOI2008]天平
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 416 Solved: 224
[Submit][Status][Discuss]
Description
你有n个砝码,均为1克,2克或者3克。你并不清楚每个砝码的重量,但你知道其中一些砝码重量的大小关系。
你把其中两个砝码A和B放在天平的左边,需要另外选出两个砝码放在天平的右边。问:有多少种选法使得天平的左
边重(c1)、一样重(c2)、右边重(c3)?(只有结果保证惟一的选法才统计在内)
Input
第一行包含三个正整数n,A,B(1<=A,B<=N,A和B不相等)。砝码编号为1~N。以下n行包含重量关系矩阵,
其中第i行第j个字符为加号“+”表示砝码i比砝码j重,减号“-”表示砝码i比砝码j轻,等号“=”表示砝码i和砝
码j一样重,问号“?”表示二者的关系未知。存在一种情况符合该矩阵
Output
仅一行,包含三个整数,即c1,c2和c3。
Sample Input
?+????
-?+???
?-????
????+?
???-?+
????-?
Sample Output
HINT
【数据规模】 4<=n<=50
#include<cstring>
using namespace std;
const int N=52;
int fa[N],l[N],r[N],g[N][N],v[N];
int ans1,ans2,ans3;
int n,A,B;
int q[N],top;
char ch[N][N];
inline int findx(int x){return x==fa[x]?fa[x]:fa[x]=findx(fa[x]);}
inline void uni(int x,int y){fa[findx(x)]=findx(y);}
inline int sgn(int x){return !x?0:(x>0?1:-1);}
int main(){
scanf("%d%d%d",&n,&A,&B);
for(int i=1;i<=n;++i) fa[i]=i;
for(int i=1;i<=n;++i){
scanf("%s",ch[i]+1);
for(int j=1;j<=n;++j) if(ch[i][j]=='=') uni(i,j);
}
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(ch[i][j]=='+') g[findx(i)][findx(j)]=1;
else if(ch[i][j]=='-') g[findx(i)][findx(j)]=-1;
for(int i=1;i<=n;++i) if(findx(i)==i) q[++top]=i;
for(int i=1;i<=top;++i){
bool L=0,R=0;
for(int j=1;j<=top;++j) L|=(g[q[i]][q[j]]==1),R|=(g[q[i]][q[j]]==-1);
if(!L||!R) continue;
v[q[i]]=2;
for(int j=1;j<=top;++j)
if(g[q[i]][q[j]]==1) v[q[j]]=1;
else if(g[q[i]][q[j]]==-1) v[q[j]]=3;
}
for(int i=1;i<=top;++i){
l[q[i]]=1,r[q[i]]=3;
if(v[q[i]]) l[q[i]]=r[q[i]]=v[q[i]];
else for(int j=1;j<=top;++j)
if(g[q[i]][q[j]]==1) l[q[i]]=2;
else if(g[q[i]][q[j]]==-1) r[q[i]]=2;
}
for(int i=1;i<n;++i) if(i!=A&&i!=B)
for(int j=i+1;j<=n;++j) if(j!=A&&j!=B)
{
int fi=findx(i),fj=findx(j),fa=findx(A),fb=findx(B);
int t1=0,t2=0,t3=0;
for(int vi=l[fi];vi<=r[fi];++vi) for(int vj=l[fj];vj<=r[fj];++vj)
for(int va=l[fa];va<=r[fa];++va) for(int vb=l[fb];vb<=r[fb];++vb)
{
int F[4]={fi,fj,fa,fb},V[4]={vi,vj,va,vb};
bool flag=1;
for(int x=0;x<4;++x) for(int y=0;y<4;++y)
if(F[x]==F[y]&&V[x]!=V[y]) {flag=false;break;}
for(int x=0;x<4;++x) for(int y=0;y<4;++y)
if(g[F[x]][F[y]]&&sgn(V[x]-V[y])!=g[F[x]][F[y]]) {flag=false;break;}
if( !flag ) continue;
if( va + vb > vi + vj ) t1 = 1;
if( va + vb == vi + vj ) t2 = 1;
if( va + vb < vi + vj ) t3 = 1;
}
if( t1 + t2 + t3 == 1 ) ans1 += t1, ans2 += t2, ans3 += t3;
}
printf("%d %d %d\n",ans1,ans2,ans3);
}
BZOJ1077 并查集的更多相关文章
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...
- 关押罪犯 and 食物链(并查集)
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- bzoj1854--并查集
这题有一种神奇的并查集做法. 将每种属性作为一个点,每种装备作为一条边,则可以得到如下结论: 1.如果一个有n个点的连通块有n-1条边,则我们可以满足这个连通块的n-1个点. 2.如果一个有n个点的连 ...
- [bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)
Description n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0& ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集
3673: 可持久化并查集 by zky Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 1878 Solved: 846[Submit][Status ...
- Codeforces 731C Socks 并查集
题目:http://codeforces.com/contest/731/problem/C 思路:并查集处理出哪几堆袜子是同一颜色的,对于每堆袜子求出出现最多颜色的次数,用这堆袜子的数目减去该值即为 ...
- “玲珑杯”ACM比赛 Round #7 B -- Capture(并查集+优先队列)
题意:初始时有个首都1,有n个操作 +V表示有一个新的城市连接到了V号城市 -V表示V号城市断开了连接,同时V的子城市也会断开连接 每次输出在每次操作后到首都1距离最远的城市编号,多个距离相同输出编号 ...
随机推荐
- 【Linux题目】第六关
[定时任务规则] 1. 如果在某用户的crontab文件中有以下记录,该行中的命令多久执行一次(RHCE考试题)?( ) 30 4 * * 3 mycmd A. 每小时. B. 每周. C. 每年三月 ...
- 关于Python的JSON
1.json模块load/loads.dump/dumps区别:(摘自这里) 实际上json就是python字典的字符串表示,但是字典作为一个复杂对象是无法直接转换成定义它的代码的字符串,python ...
- 从零搭建Prometheus监控报警系统
什么是Prometheus? Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库(TSDB).Prometheus使用Go语言开发,是Google BorgMon监控系统 ...
- CodeForces - 1176A Divide it! (模拟+分类处理)
You are given an integer nn. You can perform any of the following operations with this number an arb ...
- Android控件重叠显示小记
方案一 利用布局控件显示优先级 在xml中RelativeLayout,FrameLayout,靠后的控件显示在上层. 利用margin属性 margin属性可以控制控件间的距离,属性值为正值时,越大 ...
- Java笔记(day23-day26)
IO流1,复制一个文本文件. 1,明确体系: 源:InputStream ,Reader 目的:OutputStream ,Writer 2,明确数据: ...
- 2020 wannafly camp 补题 day1
题目可以从牛客上找到. 最简单的一个题应该是B B. 密码学 这个应该就是倒着推,题目给了你加密的顺序,所以我们逆推这个就可以得到每一次加密前的字符串. 1H. 最大公约数 题目大意就是给你一个范围1 ...
- spring类型转换
如果表单提交的时候,有的字段是字符串类型,但是后台接收到的时候是其他类型(比如日期类型),我们就可以使用类型转换来把字符串类型转换为需要的类型.当字符串类型和后台的日期类型匹配的时候,也可以不做转换, ...
- 多表同步 ES 的问题
原始需求 对跨业务域数据提供联查搜索能力. 比如:对退款单提供根据退款单.退款状态.发货状态的联查,其中退款状态和发货状态是跨业务域. 比如:对订单提供根据订单号.订单状态.退款状态的联查,其中订单状 ...
- 【Elasticsearch学习】文档搜索全过程
在ES执行分布式搜索时,分布式搜索操作需要分散到所有相关分片,若一个索引有3个主分片,每个主分片有一个副本分片,那么搜索请求会在这6个分片中随机选择3个分片,这3个分片有可能是主分片也可能是副本分片, ...