描述:给定一张图(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:

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 1010
#define maxm 5010
bool bo[maxn][maxn],b[maxn][maxn];
vector<int> e[maxn];
#define pb push_back
int n;
inline void task2(){
for (int i=;i<=n;i++)
for (int j=;j<e[i].size();j++) bo[i][e[i][j]]=;
}
inline void task3(){
for (int i=;i<=n;i++)
for (int j=;j<e[i].size();j++)
for (int k=j+;k<e[i].size();k++)
bo[e[i][j]][e[i][k]]=bo[e[i][k]][e[i][j]]=;
}
inline void task4(){
for (int i=;i<=n;i++)
for (int j=i+;j<=n;j++)
for (int k=;k<e[i].size();k++)
for (int l=;l<e[j].size();l++) {
int u=e[i][k],v=e[j][l];
if (u!=v&&u!=j&&v!=i&&b[u][v]) bo[i][j]=bo[j][i]=;
}
}
inline void task5(){
static int cnt[maxn][maxn];
memset(cnt,,sizeof(cnt));
for (int i=;i<=n;i++)
for (int j=;j<e[i].size();j++)
for (int k=j+;k<e[i].size();k++)
cnt[e[i][j]][e[i][k]]++,cnt[e[i][k]][e[i][j]]++;
for (int i=;i<=n;i++)
for (int j=i+;j<=n;j++)
for (int k=;k<e[i].size();k++)
for (int l=;l<e[j].size();l++){
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]]<=) continue;
bo[e[i][k]][e[j][l]]=bo[e[j][l]][e[i][k]]=;
}
}
inline void task6(){
static int cnt[maxn],ti[maxn];
static int is[maxn][maxn];
static int L;
for (int i=;i<=n;i++)
for (int j=i+;j<=n;j++){
L++;
int tot=;
for (int k=;k<e[i].size();k++)
for (int l=;l<e[j].size();l++)
if (e[i][k]!=e[j][l]&&e[i][k]!=j&&e[j][l]!=i&&b[e[i][k]][e[j][l]]) {
if (ti[e[i][k]]!=L) ti[e[i][k]]=L,cnt[e[i][k]]=;
if (ti[e[j][l]]!=L) ti[e[j][l]]=L,cnt[e[j][l]]=;
cnt[e[i][k]]++,cnt[e[j][l]]++,tot++,is[e[i][k]][e[j][l]]=L;
}
for (int k=;k<e[i].size();k++)
for (int l=;l<e[j].size();l++) {
if (e[i][k]==e[j][l]||e[i][k]==j||e[j][l]==i||
tot-(ti[e[i][k]]==L?cnt[e[i][k]]:)-(ti[e[j][l]]==L?cnt[e[j][l]]:)+(is[e[i][k]][e[j][l]]==L)+(is[e[j][l]][e[i][k]]==L)<=) continue;
bo[e[i][k]][e[j][l]]=bo[e[j][l]][e[i][k]]=;
}
}
}
int L;
vector<int> id[maxn][maxn];
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];
inline void addcnt(int x) {
if (is_cnt[x]!=L) is_cnt[x]=L,cnt[x]=;
cnt[x]++;
}inline void addmid(int x) {
if (is_mid[x]!=L) is_mid[x]=L,mid[x]=;
mid[x]++;
}inline void addex(int x,int y) {
if (is_ex[x][y]!=L) is_ex[x][y]=L,ex[x][y]=;
ex[x][y]++;
}inline void addside(int x,int y) {
if (is_side[x][y]!=L) is_side[x][y]=L,side[x][y]=;
side[x][y]++;
}
inline int quecnt(int x) {return is_cnt[x]==L?cnt[x]:;}
inline int quemid(int x) {return is_mid[x]==L?mid[x]:;}
inline int queex(int x,int y) {return is_ex[x][y]==L?ex[x][y]:;}
inline int queside(int x,int y) {return is_side[x][y]==L?side[x][y]:;}
inline void task7(){
for (int i=;i<=n;i++)
for (int j=;j<=n;j++) id[i][j].clear();
for (int i=;i<=n;i++)
for (int j=;j<e[i].size();j++)
for (int k=j+;k<e[i].size();k++){
id[e[i][j]][e[i][k]].pb(i);
id[e[i][k]][e[i][j]].pb(i);
}
for (int i=;i<=n;i++)
for (int j=i+;j<=n;j++){
L++;
int tot=;
for (int k=;k<e[i].size();k++)
for (int l=;l<e[j].size();l++) {
int u=e[i][k],v=e[j][l];
if (u==v||u==j||v==i) continue;
for (int r=;r<id[u][v].size();r++) {
int mid=id[u][v][r];
if (mid==i||mid==j) continue;
tot++,addcnt(u),addcnt(v);
addex(id[u][v][r],u);
addex(id[u][v][r],v);
addmid(id[u][v][r]);
addside(u,v);
}
}
for (int k=;k<e[i].size();k++)
for (int l=;l<e[j].size();l++) {
int u=e[i][k],v=e[j][l];
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)<=) continue;
bo[u][v]=bo[v][u]=;
}
}
}
int main(){
int T,m,k;
scanf("%d",&T);
while (T--) {
scanf("%d%d%d",&n,&m,&k);
for (int i=;i<=n;i++) e[i].clear();
memset(b,,sizeof(b));
memset(bo,,sizeof(bo));
for (int i=;i<=m;i++) {
int u,v;
scanf("%d%d",&u,&v);
if (u==v) continue;
if (b[u][v]) continue;
e[u].pb(v);e[v].pb(u);
b[u][v]=b[v][u]=;
}
if (k==) task2();
if (k==) task3();
if (k==) task4();
if (k==) task5();
if (k==) task6();
if (k==) task7();
for (int i=;i<=n;i++,puts(""))
for (int j=;j<=n;j++) putchar(bo[i][j]?'Y':'N');
}
return ;
}

BZOJ 4086: [Sdoi2015]travel(SDOI2015 round2 day1)(分类讨论+容斥原理)的更多相关文章

  1. BZOJ 1067 降雨量(RMQ-ST+有毒的分类讨论)

    1067: [SCOI2007]降雨量 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 4399  Solved: 1182 [Submit][Stat ...

  2. 枚举(分类讨论):BZOJ 1177: [Apio2009]Oil

    1177: [Apio2009]Oil Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1477  Solved: 589[Submit] Descri ...

  3. bzoj 3779 重组病毒 好题 LCT+dfn序+线段树分类讨论

    题目大意 1.将x到当前根路径上的所有点染成一种新的颜色: 2.将x到当前根路径上的所有点染成一种新的颜色,并且把这个点设为新的根: 3.查询以x为根的子树中所有点权值的平均值. 分析 原题codec ...

  4. Codeforces 460D Little Victor and Set --分类讨论+构造

    题意:从区间[L,R]中选取不多于k个数,使这些数异或和尽量小,输出最小异或和以及选取的那些数. 解法:分类讨论. 设选取k个数. 1. k=4的时候如果区间长度>=4且L是偶数,那么可以构造四 ...

  5. BZOJ-1067 降雨量 线段树+分类讨论

    这道B题,刚的不行,各种碎点及其容易忽略,受不鸟了直接 1067: [SCOI2007]降雨量 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 2859 ...

  6. UVaLive 6862 Triples (数学+分类讨论)

    题意:给定一个n和m,问你x^j + y^j = z^j 的数量有多少个,其中0 <= x <= y <= z <= m, j = 2, 3, 4, ... n. 析:是一个数 ...

  7. Educational Codeforces Round 63 (Rated for Div. 2) D. Beautiful Array 分类讨论连续递推dp

    题意:给出一个 数列 和一个x 可以对数列一个连续的部分 每个数乘以x  问该序列可以达到的最大连续序列和是多少 思路: 不是所有区间题目都是线段树!!!!!! 这题其实是一个很简单的dp 使用的是分 ...

  8. 【cf789B】Masha and geometric depression(分类讨论/暴力)

    B. Masha and geometric depression 题意 在黑板上写数列,首项是b,公比是q,超过l时就停止不写.给定m个数,遇到后跳过不写.问一共写多少个数,如果无穷个输出inf. ...

  9. P2331 [SCOI2005]最大子矩阵 (动规:分类讨论状态)

    题目链接:传送门 题目: 题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 输入输出格式 输入格式: 第一行为n,m,k( ...

随机推荐

  1. usb开发

    usb开发 USB HID报告及报告描述符简介 LibUSB通过SetReport()请求与USBHID设备通信 libusb开发者指南 USB枚举和HID枚举实例 USB命令 BusHound数据分 ...

  2. eclipse 完全智能提示

     1.添加智能提示 eclipse的代码提示是按”.”这个字符提示的,而如果想在其他的条件下触发,则需要按Alt + / 或者是 Ctrl + Space手动调用 (Ctrl + Space原先是Ec ...

  3. BZOJ1119[POI2009]SLO && BZOJ1697[Usaco2007 Feb]Cow Sorting牛排序

    Problem J: [POI2009]SLO Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 622  Solved: 302[Submit][Sta ...

  4. Django中扩展Paginator实现分页

    Reference:https://my.oschina.net/kelvinfang/blog/134342 Django中已经实现了很多功能,基本上只要我们需要的功能,都能够找到相应的包.要在Dj ...

  5. xlrd(开excel表格)

    打来表格 wb = xlrd.open_workbook('example.xlsx') 选择sheet sh=wb.sheet_by_index(序号) 表格的行数 sh.nrows 选取第m行第n ...

  6. Djanto static静态文件配置

    django的settings中包含三个static相关设置项: STATIC_ROOT STATIC_URL STATICFILES_DIRS   STATIC_URL 好理解,就是映射到静态文件的 ...

  7. centos 6 下编译安装 nginx

    下载nginx源码包,可以到nginx官方的下载文件归档里 http://nginx.org/download/ 下载 下载pcre源码,并编译安装,从pcre官方下载  ftp://ftp.csx. ...

  8. Aptana插件安装、配置

    本文讲解在线安装的方式: 1.eclipse->help->Install New SoftWare... 在弹出的对话框Work with中填入[http://download.apta ...

  9. jquery 编写插件入门

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <sc ...

  10. win10新特性,ubuntu子系统(安装及配置)

    最新版win10下可以直接跑ubuntu镜像,直接入正题. 这里如果你没有可能是你的版本不是最新的,我这里是最新的win10直接是有这个功能的.勾选后会要求重启,确定即可. 然后win键弹出搜索,输入 ...