d[i][j]表示从i点到j点可以全程提供光纤的公司的集合,集合用26位的二进制压缩。
那么状态转移方程就是dk[i][j]|=dk-1[i][k]&dk-1[k][j]。
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 int n,d[222][222]; 5 void Floyd(){ 6 for(int k=1; k<=n; ++k){ 7 for(int i=1; i<=n; ++i){ 8 for(int j=1; j<=n; ++j){ 9 d[i][j]|=d[i][k]&d[k][j]; 10 } 11 } 12 } 13 } 14 int main(){ 15 int a,b; 16 char str[33]; 17 while(~scanf("%d",&n) && n){ 18 memset(d,0,sizeof(d)); 19 while(~scanf("%d%d",&a,&b) && a){ 20 scanf("%s",str); 21 int c=0; 22 for(int i=0; str[i]; ++i) c|=1<<str[i]-'a'; 23 d[a][b]=c; 24 } 25 Floyd(); 26 while(~scanf("%d%d",&a,&b) && a){ 27 if(d[a][b]==0){ 28 puts("-"); 29 continue; 30 } 31 for(int i=0; i<26; ++i){ 32 if((d[a][b])>>i&1) putchar(i+'a'); 33 } 34 putchar(' '); 35 } 36 putchar(' '); 37 } 38 return 0; 39 }