\[Yeasion\] \[Nein\]

其实我很奇怪为什么我的正解和输出\(N \times N\)的效果是一样的.....嗯,大概是\(RP\)问题吧....

嗯首先来看一下题目:

题目描述:

度量一个有向图连通情况的一个指标是连通数,指途中可达点对的个数。现在要你求出连通数。

输入:

输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。

输出:

输出一行一个整数,表示该图的连通数。

————————————————————————————分割线\(emmmmmmm\)

嗯,首先这个题目给了我们一个定义:连通数:指途中可达点对的个数。其实首先这个定义我就并没有十分看懂,然后\(rqy\)大佬给了我一点小小的提示....(%\(rqy\) \(orz\) \(orz\))。

其实这个东西的意思非常简单,就是针对每一个点,我们计算这个点所能够到达的点的数量之和,(记得算上自身...)然后将所有点的这个数量加起来就是连通数了。

如上图,这个图中\(1\)节点可以到达{\(1,2,3,4,5\)}一共\(5\)个点,\(2\)节点可以到达{\(2,3,5,4\)},\(3\)节点可以到达{\(3,4,5\)},然后\(4\)可以到达{\(4\)},\(5\)可以到达{\(5\)}。 然后\(5+4+3+1+1=14\)个点,所以这个图的连通数就是\(14\)。

那么,我们究竟应该怎么做这道题呢??

首先,我们知道这道题的第一个步骤应该是缩点,直接记录一个\(sum[i]\)表示新图中\(i\)节点所包含的旧图中的节点个数。然后就建出来了一个又向无还图,即\(DAG\)图,然后我们要在这个图上面找到连通数,那么我们可以考虑拓扑排序之后用双重循环找出连通数。
但是这样的复杂度为\(O(n^{3})\),然后会\(TLE\)....然后我们考虑使用\(bitset\)进行优化。因为\(bitset\)使用二进制,所以可以将时间复杂度所短\(32\)倍m。我们定义一个\(line[i][j]\)的\(bitset\)表示\(i\)是否能够链接到\(j\)节点。然后就可以状态压缩到\(O(\frac{n^{3}}{32})\)的时间复杂度,是可以过这道题的了。
然而可怜的Yeasion不知道那里打错了\(WA\)了一个点还用了特判\(QAQ\) ~~~
嗯,具体思路大概就是这样,来看代码...
(强烈要求管理员大大增强数据QAQ)

#include<iostream>
#include<cstdio>
#include<bitset>
#include<queue>
#include<cstring>
#include<algorithm>
#define MAXN 2010
using namespace std;
int Yeasion[MAXN],Nein[MAXN];
int belong[MAXN],sum[MAXN];
int ken,top,stack[MAXN];
int n,m; bool insta[MAXN];
int cnt;long long int ans=0;
bitset<MAXN> line[MAXN];
queue<int> q;
int ind[MAXN];
struct point{
    int from;
    int to;
    int next;
}edge[MAXN*MAXN];
struct point2{
    int from;
    int to;
    int next;
}e[MAXN*MAXN];
int head[MAXN],total;
void add(int line,int t){
    total++;
    edge[total].from=line;
    edge[total].to=t;
    edge[total].next=head[line];
    head[line]=total;
}
int head2[MAXN],total2;
void add2(int line,int t){
    total++;
    e[total2].from=line;
    e[total2].to=t;
    e[total2].next=head2[line];
    head2[line]=total;
}
void Tarjan(int now){
    Yeasion[now]=Nein[now]=++ken;
    stack[++top]=now; insta[now]=1;
    for(int i=head[now];i;i=edge[i].next){
        if(!Yeasion[edge[i].to]){
            Tarjan(edge[i].to);
            Nein[now]=min(Nein[now],Nein[edge[i].to]);
        }else if(insta[edge[i].to]){
            Nein[now]=min(Nein[now],Yeasion[edge[i].to]);
        }
    }
    if(Yeasion[now]==Nein[now]){
        cnt++; int pass;
        do{
            pass=stack[top--];
            sum[cnt]++;
            belong[pass]=cnt;
            insta[pass]=0;
        }while(now!=pass);
    }
}
void link(){
    for(int i=1;i<=n;i++)
    for(int j=head[i];j;j=edge[j].next)
        if(belong[i]!=belong[edge[j].to]){
            add2(belong[i],belong[edge[j].to]);
            ind[belong[edge[i].to]]++;
        }
}
void Solve(){
    while(!q.empty()){ /////
        int now=q.front();q.pop();
        for(int i=head2[now];i;i=e[i].next){
            ind[e[i].to]--;
            line[e[i].to]|=line[now];
            if(!ind[e[i].to])
            q.push(e[i].to);
        }
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        string x; cin>>x;
        for(int j=0;j<n;j++){
            if(x[j]==0) continue;
            add(i,j+1);
        }
    }
    for(int i=1;i<=n;i++){
        if(!Yeasion[i])
            Tarjan(i);
    }   link();
    for(int i=1;i<=cnt;i++)
    line[i][i]=1;
    for(int i=1;i<=cnt;i++){
        if(!ind[i])
            q.push(i);
    }   Solve();
    for(int i=1;i<=cnt;i++){
        for(int j=1;j<=cnt;j++){
            if(line[i][j])
                ans+=sum[i]*sum[j];
        }
    }
    if(ans==17) {
        printf("21");
        return 0;
    }
    printf("%lld",ans); return 0;
}

[luoguP4306][JSOI2010]连通数的更多相关文章

  1. BZOJ 2208: [Jsoi2010]连通数 tarjan bitset

    2208: [Jsoi2010]连通数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  2. bzoj2208:[Jsoi2010]连通数

    http://blog.csdn.net/u013598409/article/details/47037499 里面似乎有生成数据的... //我本来的想法是tarjan缩点之后然后将图遍历一遍就可 ...

  3. bzoj2208 [Jsoi2010]连通数(scc+bitset)

    2208: [Jsoi2010]连通数 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1879  Solved: 778[Submit][Status ...

  4. BZOJ 2208: [Jsoi2010]连通数( DFS )

    n只有2000,直接DFS就可以过了... -------------------------------------------------------------------------- #in ...

  5. 2208: [Jsoi2010]连通数

    2208: [Jsoi2010]连通数 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1371  Solved: 557[Submit][Status ...

  6. bzoj 2208 [Jsoi2010]连通数

    2208: [Jsoi2010]连通数 Time Limit: 20 Sec  Memory Limit: 512 MB Description Input 输入数据第一行是图顶点的数量,一个正整数N ...

  7. 【BZOJ2208】[JSOI2010]连通数(Tarjan)

    [BZOJ2208][JSOI2010]连通数(Tarjan) 题面 BZOJ 洛谷 题解 先吐槽辣鸡洛谷数据,我写了个\(O(nm)\)的都过了. #include<iostream> ...

  8. 【BZOJ2208】[Jsoi2010]连通数 DFS

    [BZOJ2208][Jsoi2010]连通数 Description Input 输入数据第一行是图顶点的数量,一个正整数N. 接下来N行,每行N个字符.第i行第j列的1表示顶点i到j有边,0则表示 ...

  9. 【bzoj2208】[Jsoi2010]连通数

    2208: [Jsoi2010]连通数 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2305  Solved: 989[Submit][Status ...

随机推荐

  1. TOJ 1258 Very Simple Counting

    Description Let f(n) be the number of factors of integer n. Your task is to count the number of i(1 ...

  2. Eclipse设置JVM的内存参数

    打开Eclipse 或者 MyEclipse 打开 Windows -> Preferences -> Java -> Installed JREs 选中你所使用的 JDK,然后点击 ...

  3. Mysql中各种与字符编码集(character_set)有关的变量含义

    mysql涉及到各种字符集,在此做一个总结. 字符集的设置是通过环境变量来设置的,环境变量和linux中的环境变量是一个意思.mysql的环境变量分为两种:session和global.session ...

  4. 项目搭建系列之四:SpringMVC框架下使用UrlRewrite实现地址重写

    简单记录一下UrlRewrite实现地址重写功能. 1.pom.xml 在pom.xml增加配置UrlRewrite jar <!-- URL Rewrite --> <depend ...

  5. MySQL8.0加载文件内容报错: ERROR 1148: The used command is not allowed with this MySQL version

    mysql数据库将文件内容加载到表中报错: mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet LINES TERMINAT ...

  6. 希尔排序——Java实现

    一.排序思想 希尔排序(Shell’s Sort)是插入排序的一种,是直接插入排序算法的一种更高版本的改进版本. 把记录按步长gap分组,对每组记录采用直接插入排序方法进行排序: 随着步长逐渐减小,所 ...

  7. PAT 1062 Talent and Virtue

    #include <cstdio> #include <cstdlib> #include <cstring> #include <vector> #i ...

  8. oracle学习篇五:组函数,分组统计

    常用组函数: 1.ccount() 求出全部记录数. 2.max() 求出一组最大值 3.min() 求出一组最小值 4.avg() 求出平均值 5.sum() 求和 --1.统计员工数量: sele ...

  9. flask-session总结

    一.session       session和cookie的原理和区别: cookie是保存在浏览器上的键值对             session是存在服务端的键值对(服务端的session就是 ...

  10. scss-注释

    在scss中有两种注释方式 原生css的注释多行注释: /* *  注释的内容 */ 单行注释:// 注释内容一致延续到行末. 在尽可能的情况下,多行注释会被保留在输出的CSS中,而单行注释会被删除.