二进制真的是个神奇的东西!
类似floyd求传递闭包,这里g[i][j]表示i点到j点的状态(即符合条件的公司的集合)。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 201; 7 const int M = 31; 8 int g[N][N]; 9 int n; 10 11 int main () 12 { 13 while ( scanf("%d", &n), n ) 14 { 15 memset( g, 0, sizeof(g) ); 16 int u, v; 17 char str[M]; 18 while ( scanf("%d%d", &u, &v) != EOF ) 19 { 20 if ( !u && !v ) break; 21 scanf("%s", str); 22 int len = strlen(str); 23 for ( int i = 0; i < len; i++ ) 24 { 25 int tmp = str[i] - 'a'; 26 g[u][v] |= ( 1 << tmp ); 27 } 28 } 29 for ( int k = 1; k <= n; k++ ) 30 { 31 for ( int i = 1; i <= n; i++ ) 32 { 33 for ( int j = 1; j <= n; j++ ) 34 { 35 g[i][j] |= ( g[i][k] & g[k][j] ); 36 } 37 } 38 } 39 int p, q; 40 while ( scanf("%d%d", &p, &q) != EOF ) 41 { 42 if ( !p && !q ) break; 43 if ( !g[p][q] ) 44 { 45 putchar('-'); 46 } 47 else 48 { 49 for ( int i = 0; ( 1 << i ) <= g[p][q]; i++ ) 50 { 51 if ( g[p][q] & ( 1 << i ) ) 52 { 53 putchar( 'a' + i ); 54 } 55 } 56 } 57 putchar(' '); 58 } 59 putchar(' '); 60 } 61 return 0; 62 }