POJ2570, ZOJ1967

  题意:给你 n个点 m条边 每条边有些公司支持 问 a点到b点的路径有哪些公司可以支持
  这里是一条路径中要每段路上都要有该公司支持 才算合格的一个公司
 
  分析:map[i][j] 等于 i直接到 j 的 公司数,加上i经过中间节点到 j 的 公司数
  因为每两个站点间的公司数最多为26个,所以可以用位运算,
  用二进制去表示每个公司 1表示该路径上有该公司

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 using namespace std;
 7 #define N 205
 8 int n;
 9 int map[N][N];
10 
11 int main()
12 {
13     while(scanf("%d",&n)&&n)
14     {
15         memset(map,0,sizeof(map));
16         int u,v;
17         char s[27];
18         while(scanf("%d%d",&u,&v))
19         {
20             if(u==0&&v==0) break;
21             scanf("%s",s);
22             for(int i=0; s[i] ; i++)
23             {
24                 map[u][v] |= (1<<(s[i]-'a')); //直接从u到v有哪些公司 
25             }
26         }
27         for(int k=1; k<=n; k++)
28         {
29             for(int i=1; i<=n; i++)
30             {
31                 for(int j=1; j<=n; j++)
32                 {
33                     map[i][j] |= (map[i][k]&map[k][j]);
34                     //(map[i][k]&map[k][j])表示该路径的中间节点必须都有某个公司
35                     //然后再与 map[i][j]进行或运算 
36                 }
37             }
38         }
39         while(scanf("%d%d",&u,&v))
40         {
41             if(u==0&&v==0) break;
42             for(int i=0; i<26; i++)
43             {
44                 if(map[u][v] & (1<<i))//查询有木有某个公司 
45                 printf("%c",i+'a');
46             }
47             if(map[u][v]==0) printf("-"); //一个公司都木有 
48             printf("
");
49         }
50         printf("
");
51     }
52     return 0;
53 } 
View Code
原文地址:https://www.cnblogs.com/ar940507/p/3247168.html