题意:某条道路由一些公司修建,修建道路的公司可以提供这条路上的连通,询问哪些公司可以提供从A到B的路径.每个公司由一个小写字母表示。
思路:因为只有26个字母 所以可能用二进制去表示每个公司 1表示该路径上有该公司 比如说 1-->3 这条路径上有 abc这三个公司 则mat[1][3]
#include <iostream>
#include <stdio.h>#include <string.h>
#define maxn 500+ 10
using namespace std;
int map[maxn][maxn];
void printf(int n)
{
char s[30];
int k = 0;
int count = 0;
while(n)
{
if( n&1) // 取二进制数的末尾,如果是0就跳过,是1就输出所对对应的字母;
s[k++] = 'a' + count;
count++; //是的字母按照位输出,末尾代表‘a'前一位代表'b'一次类推;
n = n >> 1; // 把位数向前移;
}
s[k] = '\0';
printf ("%s\n",s);
}
int main()
{
int n;
int a, b;
char str[30];
while(scanf("%d",&n),n)
{
memset(map,0,sizeof(map));
while(scanf("%d%d",&a,&b) &&a && b)
{
scanf("%s",str);
for( int i = 0; str[i] !='\0'; i++)
{
map[a][b] = map[a][b] | (1<<(str[i] -'a'));
}
}
for( int k = 1; k<=n; k++)
for( int i = 1; i<=n; i++)
for( int j = 1; j<=n; j++) //注意三个循环顺序不能反,每次是根据中间节点挑选是否更新
if(map[i][k] & map[k][j]) // 根据题意得map[i][k]交map[k][j]=map[i][k]
map[i][j] = map[i][j]|(map[i][k] & map[k][j]); //最初的并上新加入的;
while(scanf("%d%d",&a ,&b) &&a&& b)
{
if (map[a][b])
printf(map[a][b]);
else
printf ("-\n");
}
printf ("\n");
}
return 0;
}