zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    JDK源码分析 – HashMap
    牛哄哄的celery
    redis数据库基础篇
    RPC的入门应用
    Python的常用模块
    消息队列之真知灼见
    面向对象编程(2)
    python3的C3算法
    面向对象编程(1)
    CRM项目之stark组件(2)
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4570361.html
Copyright © 2011-2022 走看看