• POJ--2570--Fiber Network【floyd+位运算】


    题意:一些公司决定搭建一些光纤网络。单向的,假设从第一点到第二点,有ab两个公司能够搭建,第二点到第三点有ac两个公司能够搭建,第一点到第三点有d公司能够搭建,则第一点到第三点有a、d两个公司能够搭建。a是通过第二点。d是直接连接两点。如今给你这么一个光纤网络。问某两点之间有哪些公司能够搭建起网络。


    首先这题是个多源点的。有点像最短路的思想,假设让我做我肯定硬着头皮找同样的字母,只是我看到图论书里的想法非常好,就写上来了。

    由于公司是用一个小写字母来标识的,且每一个公司的标识互不同样,也就是说最多仅仅有26个公司。因此。能够用整数中的二进制位来表示每一个公司,通过二进制位运算来实现集合的“或”运算和“与”运算。

    假设第一点到第二点有a、b、c三个公司,则可用“00000000000000000000000000000111”来表示,第二点到第三点有a、d两个公司。则可用“00000000000000000000000000001001“来表示。所以假设用edge数组表示某两点之间的公司,就能够这么更新:

    edge[i][j] |= edge[i][k] & edge[k][j]。

    然后是输入输出的处理,在读入字符串后,要用逻辑左移存入到edge数组中:edge[a][b] = 1 << (s[i]-'a')

    输出的处理。枚举字符ch从‘a’到‘z’,假设edge[a][b]&(1<<ch-'a')为1,则表示edge[a][b]所代表的集合中包括ch公司,则输出

    假设edge[a][b]==0,说明a、b之间没有公司了


    二进制和位运算真是好东西


    #include<cstring>
    #include<string>
    #include<fstream>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<set>
    #include<vector>
    #include<stack>
    #include<ctime>
    #include<cstdlib>
    #include<functional>
    #include<cmath>
    using namespace std;
    #define PI acos(-1.0)
    #define MAXN 510
    #define eps 1e-7
    #define INF 0x7FFFFFFF
    #define seed 131
    #define ll long long
    #define ull unsigned ll
    #define lson l,m,rt<<1
    #define rson r,m+1,rt<<1|1
    
    int n;
    int edge[MAXN][MAXN];
    char s[30];
    void floyd(){
        int i,j,k;
        for(k=1;k<=n;k++){
            for(i=1;i<=n;i++){
                for(j=1;j<=n;j++){
                    edge[i][j] |= edge[i][k] & edge[k][j];
                }
            }
        }
    }
    int main(){
        int i,j;
        int a,b;
        while(scanf("%d",&n),n){
            memset(edge,0,sizeof(edge));
            while(scanf("%d%d",&a,&b),a||b){
                scanf("%s",s);
                int l = strlen(s);
                for(i=0;i<l;i++){
                    edge[a][b] |= 1 << (s[i]-'a');
                }
            }
            floyd();
            while(scanf("%d%d",&a,&b),a||b){
                for(i=0;i<=26;i++){
                    if(edge[a][b]&(1<<i))     printf("%c",'a'+i);
                }
                if(!edge[a][b]) printf("-");
                printf("
    ");
            }
            printf("
    ");
        }
        return 0;
    }
    


  • 相关阅读:
    游标加标量函数
    将一个Excel文件分隔成多个
    网页抓取的一个小例子
    ajax跨域问题
    ssh连接至Ubuntu服务器时,提示以下错误:REMOTE HOST IDENTIFICATION HAS CHANGED!
    Python 实现汉诺塔问题(递归)
    Ubuntu下环境变量设置
    文件上传 jqueryForm
    Oracle数据库安装完成后相关问题的解决
    Java中16进制与字符串之间的相互转换
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/5083437.html
Copyright © 2020-2023  润新知