POJ-2570 Fiber Network---Floyd+二进制表示集合

题目链接:

https://vjudge.net/problem/POJ-2570

题目大意:

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

输入描述:

输入文件包含多个测试数据。每个测试数据第 1行为一个整数 n,代表网络中站点的个数,n = 0 代表输入结束,否则 n的范围为:1≤n≤200。站点的编号为 1, …, n。接下来列出了这些站 点之间的连接。每对连接占一行,首先是两个整数 A和B,A = B = 0 代表连接列表结束,否则 A、 B的范围为:1≤A, B≤n,表示站点 A和站点 B之间的单向连接;每行后面列出了拥有站点 A到 B之间连接的公司,公司用小写字母标识,多个公司的集合为包含小写字母的字符串。 连接列表之后,是供应商查询的列表。每个查询包含两个整数 A和B,A = B = 0 代表查询列 表结束,也代表整个测试数据结束,否则 A、B 的范围为:1≤A, B≤n,代表查询的起始和终止 站点。假定任何一对连接和查询的两个站点都不相同。

输出描述:

对测试数据中的每个查询,输出一行,为满足以下条件的所有公司的标识:这些公司可以通 过自己的线路为供应商提供从查询的起始站点到终止站点的数据通路。如果没有满足条件的公司, 则仅输出字符"-"。每个测试数据的输出之后输出一个空行。

思路:

公司最多有26个 可以用2进制来表示站点间的连接关系 如果提供站点 1 到站点 2 的连接的公司集合为{ 'a', 'b', 'c' },可以用 “00000000000000000000000000000111”表示,提供站点 2到站点 3的连接的公司集合为{ 'a', 'd' },用“00000000000000000000000000001001”表示,这两个整数进行二进制与运算后 得到“00000000000000000000000000000001”,表示通过中间站点 2,提供站点 1到站点 3的连 接的公司集合为{ 'a' }。

这样就floyd进行处理就类似最短路问题了

这里主要是转化成二进制处理集合的问题,然后就是模板的Floyd

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #include<stack>
 8 #include<map>
 9 #include<set>
10 #include<sstream>
11 #define MEM(a, b) memset(a, b, sizeof(a));
12 using namespace std;
13 typedef long long ll;
14 const int maxn = 200 + 10;
15 const int INF = 0x3f3f3f3f;
16 int T, n, m, cases, tot;
17 int Map[maxn][maxn];
18 int main()
19 {
20     while(cin >> n && n)
21     {
22         MEM(Map, 0);
23         int x, y;
24         string s;
25         while(cin >> x >> y && (x + y))
26         {
27             cin >> s;
28             for(int i = 0; i < s.size(); i++)
29             {
30                 Map[x][y] |= (1<<(s[i] - 'a'));
31             }
32         }
33         for(int k = 1; k <= n; k++)
34         {
35             for(int i = 1; i <= n; i++)
36             {
37                 for(int j = 1; j <= n; j++)
38                 {
39                     Map[i][j] |= Map[i][k] & Map[k][j];
40                 }
41             }
42         }
43         while(cin >> x >> y && (x + y))
44         {
45             if(!Map[x][y])cout<<"-"<<endl;
46             else
47             {
48                 for(int i = 0; i < 26; i++)
49                 {
50                     if(Map[x][y] & (1 << i))
51                     {
52                         cout<<(char)(i + 'a');
53                     }
54                 }
55                 cout<<endl;
56             }
57         }
58         cout<<endl;
59     }
60     return 0;
61 }

 

posted @ 2018-04-07 13:26  _努力努力再努力x  阅读(140)  评论(0编辑  收藏  举报