----------------------------------------------------------------------------

一题题目:

【Bitset】重识

一题题解:

 【Bitset】重识

  • 这个题目哪来入门再好不过了,支老板之前没有接触过这个东西,然后一点即通:就是把一个int(32位)拆成32个只放0或1的位置,然后这32个的单点操作或者32个一起操作的复杂度是O(1),所以长度位N的bitset的一次单点操作是O(1),整体操作是O(N/w),其中w=32。(long long 是64)。
  • 然后Bitset还有强大是&和|功能,以及count(1)等功能。
  • 但是Bitset最厉害的地方在于优化图论的dfs部分: 我们知道,dfs的时候对于当前点X,会继续访问和X有关联的所有点,continue忽略vis过的点。而有了bitset,我们可以直接得到有关联的,而且没有vis过的点,这样可以保证不去访问不必要的边,这在稠密图里改进极大。

 

-----------------------------------------------------------------------------

二题题目:

【Bitset】重识

二题题解:

【Bitset】重识

  • 跳过缩点建图。
  • 第一部分是求Bitset,得到每个点可以访问到的点。 
  • 第二部分求对应的权值和,巧妙的利用了分块来优化,复杂度/13。而且这个13的选择也是经过计算的,2^13<n,保证分块计算的复杂度影响小于前面的复杂度,新技能,学到了。

 

POJ3275:Ranking the Cows

 

题意:有N头奶牛,现在给出M对产奶量关系U>V,问至少还需要知道多少奶牛可以做到全部奶牛产奶关系。

思路:有向图,问至少再加多少边,使得任意两点S、T的可以到达(S到达T或者到达S)。闭包传递后不能到达的需要加边,ans++。

 至于为什么ans++,可以参考,http://www.cnblogs.com/hua-dong/p/8538980.html

 

Floyd稍微优化:    注意边少,可以加一维限制,勉强通过。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1010;
int mp[maxn][maxn];
int main()
{
    int N,M,ans,i,j,k;
    while(~scanf("%d%d",&N,&M)){
        ans=0;
        memset(mp,0,sizeof(mp));
        for(i=1;i<=M;i++){
            scanf("%d%d",&j,&k);
            mp[j][k]=1;
        }
        for(k=1;k<=N;k++)
         for(i=1;i<=N;i++)
          if(mp[i][k])
           for(j=1;j<=N;j++)
            if(mp[k][j]) mp[i][j]=1;
        for(i=1;i<=N;i++)
         for(j=i+1;j<=N;j++)
          if(!mp[i][j]&&!mp[j][i])
           ans++;
        printf("%d\n",ans);
    }
    return 0;
}
View Code

相关文章:

  • 2021-09-24
  • 2021-08-04
  • 2022-02-05
猜你喜欢
  • 2021-11-09
  • 2021-06-07
  • 2022-12-23
  • 2021-08-14
相关资源
相似解决方案