专题突破三之并查集Ⅱ——星球大战,In Touch,方格染色,Junk-Mail Filter,关押罪犯,Silver Woods,Must Be Rectangular!

文章目录

  • [JSOI2008]星球大战
  • In Touch
  • 方格染色
  • Junk-Mail Filter
  • [NOIP2010 提高组] 关押罪犯
  • Silver Woods
  • Must Be Rectangular!

[JSOI2008]星球大战

source

非常套路的,正着打击星球,逆着就是添加星球以及关系,并查集维护此时连通块个数

就是这个星球被打击前的答案

#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
#define maxn 400005
vector < int > h[maxn];
pair < int, int > p[maxn];
int n, m, k, ans;
int f[maxn], g[maxn], ret[maxn];
bool used[maxn], vis[maxn];void makeset() {for( int i = 0;i < n;i ++ ) f[i] = i;
}int find( int x ) {return x == f[x] ? x : f[x] = find( f[x] );
}void merge( int u, int v ) {u = find( u ), v = find( v );if( u ^ v ) ans --, f[v] = u;
}int main() {scanf( "%d %d", &n, &m );for( int i = 1;i <= m;i ++ ) {scanf( "%d %d", &p[i].first, &p[i].second );h[p[i].first].push_back( i );h[p[i].second].push_back( i );}scanf( "%d", &k );makeset();for( int i = 1;i <= k;i ++ )scanf( "%d", &g[i] ), used[g[i]] = 1;ans = n - k;for( int i = 1;i <= m;i ++ )if( ! used[p[i].first] and ! used[p[i].second] )merge( p[i].first, p[i].second );for( int i = k;i;i -- ) {ret[i] = ans;ans ++;used[g[i]] = 0;for( auto t : h[g[i]] )if( vis[t] ) continue;else if( used[p[t].first] or used[p[t].second] )continue;else merge( p[t].first, p[t].second );}printf( "%d\n", ans );for( int i = 1;i <= k;i ++ )printf( "%d\n", ret[i] );return 0;
}

In Touch

source

转化成最短路问题,套用dijkstra\rm dijkstradijkstra,每个点都只访问一次,但是范围那么大,用并查集帮助跳过已访问点,直指新点

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
#define Pair pair < int, int >
#define int long long
#define maxn 200005
#define inf 1e15
priority_queue < Pair, vector < Pair >, greater < Pair > > q;
int T, n;
int dis[maxn], f[maxn], L[maxn], R[maxn], c[maxn];
int MS[2] = { -1, 1 };int find( int x ) {return x == f[x] ? x : f[x] = find( f[x] );
}signed main() {scanf( "%lld", &T );while( T -- ) {scanf( "%lld", &n );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &L[i] );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &R[i] );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &c[i] );for( int i = 0;i <= n + 1;i ++ ) f[i] = i, dis[i] = inf;q.push( make_pair( dis[1] = c[1], 1 ) );while( ! q.empty() ) {int now = q.top().second; q.pop();for( int k = 0;k < 2;k ++ ) {int l = now + L[now] * MS[k];int r = now + R[now] * MS[k];if( l > r ) swap( l, r );l = min( l, n + 1 );l = max( l, 1ll );if( l > r ) continue;for( int nxt = l;;nxt ++ ) {nxt = find( nxt );if( nxt <= 0 || nxt > n || nxt > r ) break;if( dis[nxt] > dis[now] + c[nxt] ) {dis[nxt] = dis[now] + c[nxt];q.push( make_pair( dis[nxt], nxt ) );}f[find( nxt )] = find( nxt + 1 );}}}printf( "0" );for( int i = 2;i <= n;i ++ )if( dis[i] == inf ) printf( " -1" );else printf( " %lld", dis[i] - c[i] );printf( "\n" );}return 0;
}

方格染色

source

observation1: 只要确定了第一行和第一列,整张表格就被确定了

observation2: g1,1⨁gi,1⨁g1,j⨁gi,j=[imod2=0andjmod2=0]g_{1,1}\bigoplus g_{i,1}\bigoplus g_{1,j}\bigoplus g_{i,j}=[i\ \rm mod\ 2=0\ and\ j\ mod\ 2=0]g1,1gi,1g1,jgi,j=[i mod 2=0 and j mod 2=0]

可以通过枚举g1,1g_{1,1}g1,1的状态,通过已知的gi,jg_{i,j}gi,j来判断gi,1,g1,jg_{i,1},g_{1,j}gi,1,g1,j的关系

这样形成了若干组有且仅有两个选项的约束关系,带权并查集维护

连通块内有一个取值定了,其他的取值也定了

如果有解,答案就是2^(连通块数量-1),减1是g1,1g_{1,1}g1,1的状态因为是枚举的,算已知的

#include <cstdio>
#define int long long
#define mod 1000000000
#define maxn 2000005
int n, m, k;
bool flag0, flag1;
int x[maxn], y[maxn], c[maxn], f[maxn], w[maxn];int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}int find( int x ) {if( x == f[x] ) return x;else {int fa = f[x];f[x] = find( f[x] );w[x] = ( w[x] + w[fa] ) % 2;return f[x];}
}int solve() {for( int i = 1;i <= n + m;i ++ ) f[i] = i, w[i] = 0;f[n + 1] = 1;for( int i = 1;i <= k;i ++ ) {if( x[i] == 1 && y[i] == 1 ) continue;int u = find( x[i] ), v = find( y[i] + n );int t = w[x[i]] ^ w[y[i] + n] ^ c[i] ^ ( x[i] & 1 or y[i] & 1 ) ^ 1;if( u == v and t ) return 0;f[v] = u, w[v] = t;} int cnt = 0;for( int i = 1;i <= n + m;i ++ )if( find( i ) == i ) cnt ++;return qkpow( 2, cnt - 1 );
}signed main() {scanf( "%lld %lld %lld", &n, &m, &k );for( int i = 1;i <= k;i ++ ) {scanf( "%lld %lld %lld", &x[i], &y[i], &c[i] );if( x[i] == 1 && y[i] == 1 )if( ! c[i] ) flag0 = 1;else flag1 = 1;else;}int ans0 = solve();//c[g[1][1]]=0 bluefor( int i = 1;i <= k;i ++ ) c[i] ^= 1;//c[g[1][1]]=1 redint ans1 = solve();if( flag0 ) ans1 = 0;if( flag1 ) ans0 = 0;printf( "%lld\n", ( ans0 + ans1 ) % mod );return 0;
}

Junk-Mail Filter

source

可删除并查集模板

只需要注意一下被删除前的集合若只有一个,元素被删除后集合也就不存在了

#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 2200000
int n, m, ans, cnt;
int f[maxn], siz[maxn];void makeset() {cnt = n;for( int i = 0;i < n;i ++ )f[i] = f[i + n] = cnt ++, siz[i + n] = 1;
}int find( int x ) {return x == f[x] ? x : f[x] = find( f[x] );
}void merge( int u, int v ) {u = find( u ), v = find( v );if( siz[u] < siz[v] ) swap( u, v );if( u ^ v )siz[u] += siz[v], f[v] = u, ans --;
}void Delete( int x ) {int fx = find( x );siz[fx] --;if( ! siz[fx] ) ans --;f[x] = f[cnt] = cnt;siz[cnt] = 1;cnt ++;ans ++;
}int main() {int T = 0;while( scanf( "%d %d", &n, &m ) ) {if( ! n and ! m ) return 0;makeset();ans = n;char opt[5]; int x, y;for( int i = 1;i <= m;i ++ ) {scanf( "%s", opt );if( opt[0] == 'M' ) {scanf( "%d %d", &x, &y );merge( x, y );}else {scanf( "%d", &x );Delete( x );}}printf( "Case #%d: %d\n", ++ T, ans );}return 0;
}

[NOIP2010 提高组] 关押罪犯

source

贪心,先把冲突最大的安排,可以选择拆点i,i+ni,i+ni,i+n,两个人不同合并(i,j+n)/(i+n,j)(i,j+n)/(i+n,j)(i,j+n)/(i+n,j)

也可以选择带权并查集在%2\% 2%2意义下做

#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 100005
struct node {int u, v, w;node(){}node( int U, int V, int W ) {u = U, v = V, w = W;}
}r[maxn];
int n, m;
int f[maxn];void makeset() {for( int i = 1;i <= ( n << 1 );i ++ ) f[i] = i;
}int find( int x ) {return x == f[x] ? x : f[x] = find( f[x] );
}void merge( int u, int v ) {u = find( u ), v = find( v ), f[v] = u;
}int main() {scanf( "%d %d", &n, &m );for( int i = 1, u, v, w;i <= m;i ++ ) {scanf( "%d %d %d", &u, &v, &w );r[i] = node( u, v, w );}makeset();sort( r + 1, r + m + 1, []( node x, node y ) { return x.w > y.w; } );for( int i = 1;i <= m;i ++ ) {int u = r[i].u, v = r[i].v;if( find( u ) == find( v ) )return ! printf( "%d\n", r[i].w );elsemerge( u, v + n ), merge( v, u + n );}printf( "0\n" );return 0;
}

Silver Woods

source

跟一道奶酪题相似,奶酪是空心球,老鼠从底到顶;这道题是从左到右

二分半径,然后将圆卡不过的连接起来

具体而言就是点点之间距离小于直径,点和上下界面距离小于直径,合并起来

并查集判断上界面和下界面是否相通,不通证明有一种方法圆可以通过

#include <cstdio>
#include <cmath>
#define eps 1e-6
#define maxn 105
int n;
double x[maxn], y[maxn];
int f[maxn];void makeset() {for( int i = 0;i <= n + 1;i ++ ) f[i] = i;
}int find( int x ) {return x == f[x] ? x : f[x] = find( f[x] );
}void merge( int u, int v ) {u = find( u ), v = find( v ), f[v] = u;
}double dis( int i, int j ) {return sqrt( ( x[i] - x[j] ) * ( x[i] - x[j] ) + ( y[i] - y[j] ) * ( y[i] - y[j] ) );
}bool check( double r ) {double d = r * 2;makeset();for( int i = 1;i <= n;i ++ ) {if( y[i] + d >= 100 )merge( 0, i );if( y[i] - d <= -100 )merge( n + 1, i );for( int j = i + 1;j <= n;j ++ )if( dis( i, j ) < d )merge( i, j );}if( find( 0 ) == find( n + 1 ) ) return 0;else return 1;
}int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ )scanf( "%lf %lf", &x[i], &y[i] );double l = 0, r = 100, ans;while( r - l > eps ) {double mid = ( l + r ) / 2;if( check( mid ) ) ans = mid, l = mid;else r = mid;}printf( "%.6f\n", ans );return 0;
}

Must Be Rectangular!

source

img

对于每个坐标(xi,yi)(xi,yi)(xi,yi)xixixiyi+nyi+nyi+n连边,形成一个二分图

然后后续添加点实际上就是对这个二分图的每个分量补成完全二分图

并查集维护一下二分图的边的个数,两个部的点的个数

#include <cstdio>
#define maxn 100000
int n;
int f[maxn << 2], row[maxn << 2], col[maxn << 2];void makeset() {for( int i = 1;i <= ( maxn << 1 );i ++ )f[i] = i;
}int find( int x ) {return x == f[x] ? x : f[x] = find( f[x] );
}void merge( int u, int v ) {u = find( u ), v = find( v ), f[v] = u;
}int main() {scanf( "%d", &n );makeset();for( int i = 1, x, y;i <= n;i ++ ) {scanf( "%d %d", &x, &y );merge( x, y + maxn );}long long ans = 0;for( int i = 1;i <= maxn;i ++ ) row[find( i )] ++;for( int i = 1;i <= maxn;i ++ ) col[find( i + maxn )] ++;for( int i = 1;i <= maxn;i ++ ) ans += 1ll * row[i] * col[i];printf( "%lld\n", ans - n );return 0;
}

{
u = find( u ), v = find( v ), f[v] = u;
}

int main() {
scanf( “%d”, &n );
makeset();
for( int i = 1, x, y;i <= n;i ++ ) {
scanf( “%d %d”, &x, &y );
merge( x, y + maxn );
}
long long ans = 0;
for( int i = 1;i <= maxn;i ++ ) row[find( i )] ++;
for( int i = 1;i <= maxn;i ++ ) col[find( i + maxn )] ++;
for( int i = 1;i <= maxn;i ++ ) ans += 1ll * row[i] * col[i];
printf( “%lld\n”, ans - n );
return 0;
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317239.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模板:整体二分

所谓整体二分&#xff0c;就是对整体进行二分 &#xff08;逃&#xff09; 前言 又是一个狂艹树套树的小清新分治算法 但是树套树不需要动脑啊 整体二分有一些比较重要的条件&#xff1a; 修改对判定答案的贡献互相独立&#xff0c;修改之间互不影响效果修改如果对判定答案有…

JavaWeb --第二章 Tomact详情

JavaWeb --第二章 Tomact详情 文章目录Tomcat安装TomcatTomcat启动和配置配置发布一个web网站Tomcat 安装Tomcat 去官方下载 https://tomcat.apache.org Tomcat启动和配置 文件夹作用&#xff1a; 启动/关闭 Tomcat&#xff1a; 文件夹bin/startup.bat 开启 网址&#x…

P8352-[SDOI/SXOI2022]小N的独立集【dp套dp】

正题 题目链接:https://www.luogu.com.cn/problem/P8352 题目大意 给出一棵树&#xff0c;每个点的权值是[1,k][1,k][1,k]之间的一个数&#xff0c;对于i∈[1,nk]i\in[1,nk]i∈[1,nk]求令这棵树的最大独立集权值为iii的方案数。 1≤n≤1000,1≤k≤51\leq n\leq 1000,1\leq k\…

开源的类似于Apache ab的压力测试命令行工具SuperBenchmarker

SuperBenchmarker 是ㄧ个开源的类似于Apache ab的压力测试命令行工具。可以在 .NET 4.52 或者 .NET Core 2.0 平台上运行。可支持Get、Post、Put、Delete这些调用方式&#xff0c;调用时能指定Concurrent user、Request数、Header template…等。可以从Github、Chocolatey这两种…

CodeForces:643(VK cup)

文章目录前言CF643A Bear and ColorsDescription\text{Description}DescriptionSolution\text{Solution}SolutionDescription\text{Description}DescriptionCF643B Bear and Two PathsDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}…

一二三系列之优先队列、st表——Battle,Heapsort,A Magic Lamp

文章目录BattleHeapsortA Magic LampBattle source 如果怪兽先死&#xff0c;那么英雄血量不足也没关系 反悔贪心 每次都先杀怪兽再说&#xff0c;如果血量不够了&#xff0c;就倒回去从怪兽打出伤害由高到低反悔&#xff0c;选择抵御或者加血&#xff0c;肯定哪个加的更多…

JavaWeb --第三章 HTTP协议详解

JavaWeb --第三章 HTTP协议详解 Http 什么是HTTP HTTP&#xff1a; 超文本传输协议&#xff08;Hypertext Transfer Protocol&#xff0c;HTTP&#xff09;是一个简单的请求-响应协议&#xff0c;它通常运行在TCP之上。 文本&#xff1a;html&#xff0c;字符串&#xff0c…

AT2382-[AGC015D]A or...or B Problem

正题 题目链接:https://www.luogu.com.cn/problem/AT2382 题目大意 询问在[L,R][L,R][L,R]中选取一个或多个数&#xff0c;将它们按位或后能得到多少种不同的结果。 1≤L≤R<2601\leq L\leq R<2^{60}1≤L≤R<260 解题思路 我们先把高位的LLL和RRR都有的111都删除&a…

数据结构一【树状数组】普通、二维、离线树状数组的(单点修改,单点查询,区间修改,区间查询)模板及应用例题总结

文章目录树状数组lowbit线段树与树状数组单点修改区间查询区间修改区间求和二维树状数组离线树状数组例题POJ&#xff1a;starsMooFest[SDOI2009]HH的项链Turing TreeCounting SequencesZip-line树状数组 用于快速高效的计算与前缀和相关的信息 lowbit int lowbit( int i ) …

如何优雅的利用Windows服务来部署ASP.NET Core程序

上一篇文章中我给大家讲述了五种部署ASP.NET Core网站的方法&#xff0c;其中有一种方式是通过Windows服务来进行部署&#xff0c;这样既可以做到开启自启动&#xff0c;又不会因为iis的反向代理而损失部分性能。但是美中不足的是需要借助第三方软件nssm来进行&#xff0c;那么…

JavaWeb --第四章Maven详解

JavaWeb --第四章Maven详解 文章目录MavenMaven架构管理工具下载安装Maven配置环境变量阿里云镜像本地仓库在IDEA中使用Maven创建一个普通的Maven项目在IDEA中标记文件夹功能在IDEA中配置tomcatpom文件IDEA操作解决遇到的问题Maven 为什么要学这个技术&#xff1f; 在javaweb…

P3242 [HNOI2015] 接水果(整体二分、扫描线、dfs序)

解析 一道有点毒瘤的题 也是一道感觉真的可以出现在考场上的很综合的题 做的还可以 除了一开始把盘子和水果看反白写了各树套树之外 为什么盘子是水果的子路径啊 由于是做专题爬过来的多次询问区间第k小&#xff0c;想到整体二分 那么重点就是子路径的判定问题 发现&#xff…

UOJ#748-[UNR #6]机器人表演【dp】

正题 题目链接:https://uoj.ac/problem/748 题目大意 有一个长度为nnn的010101序列&#xff0c;然后ttt次插入一个000和一个111&#xff0c;要求000在111前面&#xff0c;求最终能得到多少种本质不同的串。 1≤n,t≤3001\leq n,t\leq 3001≤n,t≤300 解题思路 我们考虑一个n…

夯实基础项目工程之图论——Uncle Bogdan and Country Happiness,Graph Coloring,How Many Paths?,Array Differentiation

文章目录做题情况项目报告Uncle Bogdan and Country HappinessGraph ColoringHow Many Paths?Array Differentiation做题情况项目报告 T1,T3T1,T3T1,T3一眼题&#xff0c;在实现上&#xff0c;T3T3T3耗时略长&#xff08;有些情况未考虑到位&#xff09; T4T4T4感觉题&#xf…

Codeforces Round #716 (Div. 2)

Codeforces Round #716 (Div. 2) CodeForces 1514 题号题目知识点难度APerfectly Imperfect ArrayBAND 0, Sum BigCProduct 1 Modulo NDCut and StickEBaby Ehab’s Hyper Apartment

用StyleCop规范团队代码

前言编码风格&#xff0c;每个人都是有不同的特点&#xff0c;风格各异&#xff0c;而且一个人在不同的时期&#xff0c;编码风格的差异也可能是非常大的&#xff0c;好比学生时代&#xff0c;刚工作的时候&#xff0c;工作一段时间后等。在一个团队中&#xff0c;或一个项目中…

CodeForces:103(div1)104(div2)

文章目录前言CF104A BlackjackDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF103A Testing Pants for SadnessDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF103B CthulhuDe…

UOJ#749-[UNR #6]稳健型选手【贪心,分治,主席树】

正题 题目链接:https://uoj.ac/problem/749 题目大意 如果有序列aaa&#xff0c;你每次取走一个数字后然后这个序列最前面的数字会被别人取走&#xff0c;直到序列为空。此时f(a)f(a)f(a)表示你最大能取走的权值和。 给出一个长度为nnn的序列aaa&#xff0c;qqq次询问区间[l…

A. And Then There Were K

A. And Then There Were K 题意&#xff1a; 给你一个n&#xff0c;让你求一个k&#xff0c;使得满足下列式子&#xff1a; n & (n-1) & (n-2) &…&(k) 0 问k最小是多少&#xff1f; 题解&#xff1a; 找规律 比如n的二进制为&#xff1a;1111 那么n-1就是…

一键发布部署vs插件[AntDeploy],让net开发者更幸福

一键发布工具(ant deploy tool)插件下载地址&#xff1a;https://marketplace.visualstudio.com/items?itemNamenainaigu.AntDeploy1.iis一键发布自动部署 (iis deploy support)支持netcore 和 netframework发布 (支持mvc webapi)支持website自动创建ps:需要在windows 服务器上…