POJ2570, ZOJ1967
题意:给你 n个点 m条边 每条边有些公司支持 问 a点到b点的路径有哪些公司可以支持
这里是一条路径中要每段路上都要有该公司支持 才算合格的一个公司
分析:map[i][j] 等于 i直接到 j 的 公司数,加上i经过中间节点到 j 的 公司数
因为每两个站点间的公司数最多为26个,所以可以用位运算,
用二进制去表示每个公司 1表示该路径上有该公司
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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("\n"); 49 } 50 printf("\n"); 51 } 52 return 0; 53 }