BZOJ 4086: [Sdoi2015]travel(SDOI2015 round2 day1)(分类讨论+容斥原理)
描述:给定一张图(n<1000,m<5000)求有多少点对u,v有不重复经过其他点,共经过k个点的路径。(k<=7)
这个做法应该不是正解吧。。顺便说下SDOI的几道题在BZ上都要卡常数真是哭瞎了QAQ
然后我们知道k这么小,考虑下每个k怎么乱搞吧。。。
k=2:直接枚举每条边就行啦
k=3:枚举中间点,然后再考虑两端端点O(m^2)
k=4:枚举两边的点,然后枚举边考虑中间的两个点是否联通O(m^2)
k=5:枚举夹在中间的两个点,然后记录所有可能的中间点数目tot,然后枚举外面的两点,若tot-两点是否为中间点>0那么就可行
k=6:思路大概相同,记链为x->u->p->q->v->y 枚举u,v记下所有可能的二元组p,q,记总数为tot,出现x的次数为Cx,然后在枚举x,y若tot-Cx-Cy+x,y是否为二元组>0,那么就可行
k=7:依旧是考虑容斥,记链为x->u->p->z->q->v->y,先记下对所有p,q中z的集合,然后枚举u,v,对中间的所有可行的三元组,记录总数为tot,x在两端出现次数为Cx,在中间次数为Mx
x在中,y在两端的次数为ESx,y;x,y都在两端的次数为Sx,y,再枚举x,y,若tot-Cx-Cy-Mx-My+MSx,y+MSy,x+Sx,y>0,那么可行
对于k<7的情况可以O(m^2)完成,K=7的情况有点难估计(O(M^2*N)大概吧)不过能过就对了
好啦好像很短但还是写了5KB左右,主要思路还是分情况讨论然后枚举端点上容斥啦
CODE:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 using namespace std; 7 #define maxn 1010 8 #define maxm 5010 9 bool bo[maxn][maxn],b[maxn][maxn]; 10 vector<int> e[maxn]; 11 #define pb push_back 12 int n; 13 inline void task2(){ 14 for (int i=1;i<=n;i++) 15 for (int j=0;j<e[i].size();j++) bo[i][e[i][j]]=1; 16 } 17 inline void task3(){ 18 for (int i=1;i<=n;i++) 19 for (int j=0;j<e[i].size();j++) 20 for (int k=j+1;k<e[i].size();k++) 21 bo[e[i][j]][e[i][k]]=bo[e[i][k]][e[i][j]]=1; 22 } 23 inline void task4(){ 24 for (int i=1;i<=n;i++) 25 for (int j=i+1;j<=n;j++) 26 for (int k=0;k<e[i].size();k++) 27 for (int l=0;l<e[j].size();l++) { 28 int u=e[i][k],v=e[j][l]; 29 if (u!=v&&u!=j&&v!=i&&b[u][v]) bo[i][j]=bo[j][i]=1; 30 } 31 } 32 inline void task5(){ 33 static int cnt[maxn][maxn]; 34 memset(cnt,0,sizeof(cnt)); 35 for (int i=1;i<=n;i++) 36 for (int j=0;j<e[i].size();j++) 37 for (int k=j+1;k<e[i].size();k++) 38 cnt[e[i][j]][e[i][k]]++,cnt[e[i][k]][e[i][j]]++; 39 for (int i=1;i<=n;i++) 40 for (int j=i+1;j<=n;j++) 41 for (int k=0;k<e[i].size();k++) 42 for (int l=0;l<e[j].size();l++){ 43 if (i==j||e[i][k]==e[j][l]||e[i][k]==j||e[j][l]==i||cnt[i][j]-b[i][e[j][l]]-b[j][e[i][k]]<=0) continue; 44 bo[e[i][k]][e[j][l]]=bo[e[j][l]][e[i][k]]=1; 45 } 46 } 47 inline void task6(){ 48 static int cnt[maxn],ti[maxn]; 49 static int is[maxn][maxn]; 50 static int L; 51 for (int i=1;i<=n;i++) 52 for (int j=i+1;j<=n;j++){ 53 L++; 54 int tot=0; 55 for (int k=0;k<e[i].size();k++) 56 for (int l=0;l<e[j].size();l++) 57 if (e[i][k]!=e[j][l]&&e[i][k]!=j&&e[j][l]!=i&&b[e[i][k]][e[j][l]]) { 58 if (ti[e[i][k]]!=L) ti[e[i][k]]=L,cnt[e[i][k]]=0; 59 if (ti[e[j][l]]!=L) ti[e[j][l]]=L,cnt[e[j][l]]=0; 60 cnt[e[i][k]]++,cnt[e[j][l]]++,tot++,is[e[i][k]][e[j][l]]=L; 61 } 62 for (int k=0;k<e[i].size();k++) 63 for (int l=0;l<e[j].size();l++) { 64 if (e[i][k]==e[j][l]||e[i][k]==j||e[j][l]==i|| 65 tot-(ti[e[i][k]]==L?cnt[e[i][k]]:0)-(ti[e[j][l]]==L?cnt[e[j][l]]:0)+(is[e[i][k]][e[j][l]]==L)+(is[e[j][l]][e[i][k]]==L)<=0) continue; 66 bo[e[i][k]][e[j][l]]=bo[e[j][l]][e[i][k]]=1; 67 } 68 } 69 } 70 int L; 71 vector<int> id[maxn][maxn]; 72 int is_cnt[maxn],cnt[maxn],ex[maxn][maxn],is_ex[maxn][maxn],mid[maxn],is_mid[maxn],side[maxn][maxn],is_side[maxn][maxn]; 73 inline void addcnt(int x) { 74 if (is_cnt[x]!=L) is_cnt[x]=L,cnt[x]=0; 75 cnt[x]++; 76 }inline void addmid(int x) { 77 if (is_mid[x]!=L) is_mid[x]=L,mid[x]=0; 78 mid[x]++; 79 }inline void addex(int x,int y) { 80 if (is_ex[x][y]!=L) is_ex[x][y]=L,ex[x][y]=0; 81 ex[x][y]++; 82 }inline void addside(int x,int y) { 83 if (is_side[x][y]!=L) is_side[x][y]=L,side[x][y]=0; 84 side[x][y]++; 85 } 86 inline int quecnt(int x) {return is_cnt[x]==L?cnt[x]:0;} 87 inline int quemid(int x) {return is_mid[x]==L?mid[x]:0;} 88 inline int queex(int x,int y) {return is_ex[x][y]==L?ex[x][y]:0;} 89 inline int queside(int x,int y) {return is_side[x][y]==L?side[x][y]:0;} 90 inline void task7(){ 91 for (int i=1;i<=n;i++) 92 for (int j=1;j<=n;j++) id[i][j].clear(); 93 for (int i=1;i<=n;i++) 94 for (int j=0;j<e[i].size();j++) 95 for (int k=j+1;k<e[i].size();k++){ 96 id[e[i][j]][e[i][k]].pb(i); 97 id[e[i][k]][e[i][j]].pb(i); 98 } 99 for (int i=1;i<=n;i++) 100 for (int j=i+1;j<=n;j++){ 101 L++; 102 int tot=0; 103 for (int k=0;k<e[i].size();k++) 104 for (int l=0;l<e[j].size();l++) { 105 int u=e[i][k],v=e[j][l]; 106 if (u==v||u==j||v==i) continue; 107 for (int r=0;r<id[u][v].size();r++) { 108 int mid=id[u][v][r]; 109 if (mid==i||mid==j) continue; 110 tot++,addcnt(u),addcnt(v); 111 addex(id[u][v][r],u); 112 addex(id[u][v][r],v); 113 addmid(id[u][v][r]); 114 addside(u,v); 115 } 116 } 117 for (int k=0;k<e[i].size();k++) 118 for (int l=0;l<e[j].size();l++) { 119 int u=e[i][k],v=e[j][l]; 120 if (u==v||u==j||v==i||tot-quecnt(u)-quecnt(v)-quemid(u)-quemid(v)+queex(u,v)+queex(v,u)+queside(u,v)<=0) continue; 121 bo[u][v]=bo[v][u]=1; 122 } 123 } 124 } 125 int main(){ 126 int T,m,k; 127 scanf("%d",&T); 128 while (T--) { 129 scanf("%d%d%d",&n,&m,&k); 130 for (int i=1;i<=n;i++) e[i].clear(); 131 memset(b,0,sizeof(b)); 132 memset(bo,0,sizeof(bo)); 133 for (int i=1;i<=m;i++) { 134 int u,v; 135 scanf("%d%d",&u,&v); 136 if (u==v) continue; 137 if (b[u][v]) continue; 138 e[u].pb(v);e[v].pb(u); 139 b[u][v]=b[v][u]=1; 140 } 141 if (k==2) task2(); 142 if (k==3) task3(); 143 if (k==4) task4(); 144 if (k==5) task5(); 145 if (k==6) task6(); 146 if (k==7) task7(); 147 for (int i=1;i<=n;i++,puts("")) 148 for (int j=1;j<=n;j++) putchar(bo[i][j]?'Y':'N'); 149 } 150 return 0; 151 }
View Code
转载于:https://www.cnblogs.com/New-Godess/p/4570361.html
BZOJ 4086: [Sdoi2015]travel(SDOI2015 round2 day1)(分类讨论+容斥原理)相关推荐
- 模拟赛Day1(20200203) T1 垃圾题【分类讨论+枚举+dp解决等价匹配问题】
题目描述: 题目分析: 看到bbb的长度为5,可以感觉到这题就是在锻炼强大合理的分类讨论能力. 首先看bi≤2b_i\le2bi≤2的部分分,即只有两种数字. 枚举这两种数为x,yx,yx,y,数量 ...
- 分类讨论 ---- 2020 icpc 上海 Walker (二分 or 思维分类讨论)
题目链接 题目大意: 就是两个人在坐标轴上面,有起始的坐标p1,p2p1,p2p1,p2,和速度v1,v2v1,v2v1,v2,问你访问完这长度为nnn的数轴最短时间是多少? 解题思路: 大佬有直接二 ...
- CF1471 D - Strange Definition(思维,分类讨论,lcm,gcd的性质,数论)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #694 (Div. 2) D 很好的一道数论思维题 D - Str ...
- Unfair contest 模拟-分类讨论
题意 : 两人比赛,n个裁判,给分范围[1,h][1, h][1,h],去掉s个最高分和t个最低分,给出n - 1个裁判的给分,第n个裁判想让第1个人赢,并且最小化给1的分数a[n]a[n]a[n] ...
- 2020ICPC(上海) - Walker(分类讨论+二分)
题目链接:点击查看 题目大意:在长度为 n 的数轴上给出两个人的初始位置和速度,问使得每个位置至少被一个人走过的时间是多少 题目分析:分类讨论题目,分四种情况讨论即可,设 p1 < p2: p1 ...
- 【UOJ#33】【UR #2】树上GCD(长链剖分/根号分类讨论)
[UOJ#33][UR #2]树上GCD 求解树上两个点到lca的距离的最大公约数是k的对数 首先我们很容易就想到莫比乌斯反演,那么利用倍数形式,我们只需要求解是i的倍数的对数. 考虑枚举lca,这个 ...
- uoj#246. 【UER #7】套路(dp+分块?分类讨论?)
题目链接 分析: 目前为止我只能理解dp部分 我就喜欢这种单纯不做作的题目 一看名字就明白了这道题的本质 中二的题目描述 很显然,我们的关键就是求出最小相似度 朴素算法n^4 如果我们现在有一个权值数 ...
- Vasya and Multisets CodeForces - 1051C 模拟|分类讨论
题意:把数组分成两个集合 每个集合中元素数量为1的个数相同(此个数可以是0) 分析: 这类问题就是要各种可能情况考虑到 然后分类讨论 完整地正确分类就AC 否则gg 如果数量为 ...
- P3842 [TJOI2007]线段(线性dp,分类讨论)
P3842 [TJOI2007]线段 题意 [TJOI2007]线段 题目描述 在一个 n×nn \times nn×n 的平面上,在每一行中有一条线段,第 iii 行的线段的左端点是(i,Li)(i ...
最新文章
- 通过SecureCRT连接Vmware中的RHEL6.3的方法
- git push origin master Connection timed out
- .NET Core 1.1 升级公告
- 腾讯Node.js基础设施TSW正式开源
- 为什么有些没读过书的人做生意却很厉害?
- 01背包问题笔记(转载)
- CNN训练可视化特征图(tensorflow2.x实现)
- 数据治理的目的与意义
- 智慧灯杆解决方案之智慧景区建设
- Android绘图(二)使用 Graphics2D 实现动态效果
- Excel VLOOKUP 多条件使用
- 阿里云主机迁移 配置域名解析 顶级域名配置子域名
- hdu1512 Monkey King
- 安徽科技学院2017-2018-1学期15电信12班《Java编程技术》课下作业~解题报告
- 攻防世界007 伪造xff_referer
- ubuntu16.04开机自动挂载nas盘
- 智能优化算法:CEC23组常用测试函数公式介绍
- vs如何发布exe并附带动态链接库dll
- Linux系统管理16:shell
- 如何进行Android、IOS APP的自动化测试—东舟自动化测试解决方案
热门文章
- javascript控制validator
- c++ map 析构函数_C++学习刷题6--C++类的使用:构造函数、析构函数和类的使用
- 易能变频器说明书故障代码_易能变频器故障代码大全是什么?E013故障是什么?...
- bigint对应java什么类型_「JAVA」从格式化输出到扫描输入,深究Java正则表达式匹配之道
- python中add函数_如何使用python中的add函数?
- spark和python的关系_spark submit和pyspark有什么区别?
- rocketmq 消息指定_RocketMq 实际案例–普通消息的发送
- linux18.04安装显卡驱动,详细介绍ubuntu18.04安装NVIDIA显卡驱动(亲测有效!)
- 无法启动程序,拒绝访问解决方法
- solidworks完全卸载安装高版本