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("\n");
        }
        printf("\n");
    }
    return 0;
}

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

时间: 2024-10-06 00:53:16

POJ--2570--Fiber Network【floyd+位运算】的相关文章

Poj 2570 Fiber Network Floyd思想处理

感觉非常有意思,也不难想. f[i][j] |= f[i][k] & f[k][j] #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <

poj 2570 Fiber Network(floyd)

#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int mp[30][250][250]; int main() { int n,u,v,i,j,l,k,p,f; char s[1024]; while(~scanf("%d",&n)) { if(n==0) break; memset(mp,0,sizeof(mp)); while(~

poj 2570 Fiber Network (Floyd)

Fiber Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3107   Accepted: 1427 Description Several startup companies have decided to build a better Internet, called the "FiberNet". They have already installed many nodes that ac

POJ 2570 Fiber Network(最短路 二进制处理)

题目翻译 一些公司决定搭建一个更快的网络,称为"光纤网".他们已经在全世界建立了许多站点,这 些站点的作用类似于路由器.不幸的是,这些公司在关于站点之间的接线问题上存在争论,这样"光纤网"项目就被迫终止了,留下的是每个公司自己在某些站点之间铺设的线路. 现在,Internet 服务供应商,当想从站点 A传送数据到站点 B,就感到困惑了,到底哪个公司 能够提供必要的连接.请帮助供应商回答他们的查询,查询所有可以提供从站点 A到站定 B的线 路连接的公司. 输入描述:

POJ 2570 Fiber Network

最短路变形. 题意是说不同的点之间有不同的公司建立了不同连接. 询问 A,B之间如果存在通路,有那些公司. 我用bool  g[][][26] 来表示26个字母.然后Floyd, G++就超时.C++ 就AC了. 然后看别人代码才知道还有位运算--ORZ... 自己的代码:C++ AC.813ms #include<cstdio> #include<cstring> #include<string> #include<queue> #include<a

ZOJ 1967 POJ 2570 Fiber Network

枚举起点和公司,每次用DFS跑一遍图,预处理出所有的答案.询问的时候很快就能得到答案. #include<cstdio> #include<cmath> #include<cstring> #include<vector> #include<algorithm> using namespace std; int jz[300][300][30]; int ans[300][300][30]; int flag[300]; vector<in

POJ 2579 Fiber Network(状态压缩+Floyd)

Fiber Network Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3328   Accepted: 1532 Description Several startup companies have decided to build a better Internet, called the "FiberNet". They have already installed many nodes that ac

poj 2799 IP Networks 模拟 位运算

poj链接:http://poj.org/problem?id=2799 这题实在是非常的有趣... 写的时候也非常的开心... 然后就写跪了... 刚好讲了ip地址和子网掩码的只是 整个学期的通信导论我就只有这节课有事没去结果昨晚把这方面的只是补起来了有种功德圆满的感觉 network address是前(32-n)随意 后n位全零 network mask是前(32-n)全一 后n位全零 其次是练习了各种移位操作 我发现移位操作是个非常好用的东西 因为它自填充0 所以对一个二进制数往右移8位

zoj1967 poj2570 Fiber Network (floyd算法)

虽然不是最短路,但是询问时任意两点之间的信息都要知道才能回答,由此联想到floyd算法,只要都floyd算法的原理理解清楚了就会发现:这道题的思想和求任意两点之间的最短路的一样的,只不过是更新的信息不同而已. 这道题还有一个难点在于状态压缩:如果直接用字符串来表示maps[i][j],那么在floyd中还需要再加一层循环来找maps[i][k]和maps[k][j]有哪些一样的字母,这样时间复杂度太高,实际测试表明会TLE.那么可以用状态压缩的技巧,用二进制表示集合,最多就26位(代表26个字母