描述:给定一张图(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. NLPIR中文分词器的使用

    一.普通java项目 (1)添加项目jar包 File -> Project Structure     Libarries 添加jar包jna-4.0.0.jar (2)将Data文件夹复制到 ...

  2. vi的基本操作

    vi的基本操作 a) 进入vi 在系统提示符号输入vi及文件名称后,就进入vi全屏幕编辑画面: $ vi myfile 不过有一点要特别注意,就是您进入vi之后,是处于「命令行模式(command m ...

  3. excel导入到Orcle

    Excel导入到Oracle中 在Oracle中创建一个表,与excel的表头对应 将excel文件保存为.csv格式 创建一个.ctl文件 load data infile 'd:\xiaoyou. ...

  4. scrapy setting 备注

    scrapy 脚本里面设置输出文件: process = CrawlerProcess(settings) process.settings.set('FEED_URI', 'wangyi.csv', ...

  5. android模拟器网络设置(局域网)

    Android模拟器如何设置DNS访问局域网内网站 我们需要用到android-sdk开发包中adb shell指令 见下图

  6. loading.io一个可以直接生成loading gif图标的站点

    官网是:http://loading.io/ 进去后,可以拖动左图大小,然后点右边的make gif就可以自动生成所选大小的gif图标了,生成后会弹出一个download窗,点download下载即可 ...

  7. VS2010中出现无法嵌入互操作类型(转)

    针对word或excel操作时,出现VS2010中,无法嵌入互操作类型“……”,请改用适用的接口的解决方法问了度娘,解决方法如出一辙:选中项目中引入的dll,鼠标右键,选择属性,把“嵌入互操作类型”设 ...

  8. C# Linq to sql 实现 group by 统计多字段 返回多字段

    Linq to sql 使用group by 统计多个字段,然后返回多个字段的值,话不多说,直接上例子: where u.fy_no == fy_no orderby u.we_no group u  ...

  9. Flex中操作XML的E4X方法

    用于处理 XML 的 E4X 方法 Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本   ECMAScript for XML 规范定义了一组用于使用 XML 数据的类 ...

  10. doubango(1)--从协议栈结构说起

    自顶向下与自底向上 软件设计的两种方法不过于自顶向下与自底向上. 对于自顶向下而言,先设计好用户接口,再往下延伸至各个功能块的具体实现.而对于自底向上而言,自然是有了设计好的各个功能代码块,再将这些功 ...