\[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. flume 自定义sink

    http://flume.apache.org/FlumeDeveloperGuide.html#sink 看了 还是比较好上手的,简单翻译一下 sink的作用是从 Channel 提取 Event  ...

  2. TOJ 2888 Pearls

    Description In Pearlania everybody is fond of pearls. One company, called The Royal Pearl, produces ...

  3. PHP Mongodb API参考

    <?php /*** Mongodb类** examples: * $mongo = new HMongodb("127.0.0.1:11223"); * $mongo-&g ...

  4. Codeforce 609 C—— Load Balancing ——————【想法题】

    C. Load Balancing time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  5. FZU 1924——死锁——————【topo判环】

    死锁 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Pr ...

  6. 吴恩达《Machine Learning Yearning》总结(21-30章)

    21.偏差和方差举例 前提:对于人类而言,可以达到近乎完美的表现(即人类去做分类是误差可以接近0). (1)假设算法的表现如下:训练误差率:1%,开发误差率:11%:此时即为高方差(high vari ...

  7. 移动端H5页面注意事项

    1. 单个页面内容不能过多 设计常用尺寸:7501334 / 6401134,包含了手机顶部信号栏的高度. 移动端H5活动页面常常需要能够分享到各种社交App中,常用的有微信.QQ等. 使用移动设备查 ...

  8. 【学习笔记】2017年7月18日MySQL测试:模拟QQ数据库

    模拟测试: QQ数据库管理 一.创建数据库并添加关系和测试数据 ##创建QQ数据库,完成简单的测试 #创建数据库 DROP DATABASE IF EXISTS MyQQ; CREATE DATABA ...

  9. iOS开发之GCD基础

    重新回顾.学习GCD.Block.先贴出一篇不错的讲解GCD基础使用的文章 原文地址:http://blog.csdn.net/aolan1108/article/details/17283415 做 ...

  10. scp命令的使用

    scp命令是什么 scp是 secure copy的缩写, scp是linux系统下基于ssh登陆进行安全的远程文件拷贝命令. scp命令用法 scp [-1246BCpqrv] [-c cipher ...