POJ 2570(floyd)
http://poj.org/problem?id=2570
题意:在海底有一些网络节点。每个节点之间都是通过光缆相连接的。不过这些光缆可能是不同公司的。
现在某个公司想从a点发送消息到b点,问哪个公司可以提供这个服务。
首先输入一共有几个公司。
其次输入的是a,b两点之间的光缆是由哪几个公司提供的。0 0结束。
然后询问a,b之间是否可以有公司提供服务,有就输出那个公司,没有的话就输出-
思路:当我看到这个题,我也不知道具体怎么去操作,然后百度了一下,发现了一个人的思路很好。对于a-z这些字母。全部都是用2进制来表示
比如 abc,那么用二进制表示的也就是00000000000000000000000111,如果这个公司有服务的话,那么这个位置也就是1
然后在判断的时候,通过与或来进行判断
二进制的或 | 就是在同一个二进制位,有1则为1。 比如 0101 | 1000 答案是 1101。
二进制的与 & 就是在同一个二进制位,两个都是1才为1, 比如 1010 & 1001 答案是 1000。
二进制的取反 ~ 就是在这个二进制数中,1全部变成0,0全部变成1 比如 ~1100 答案是 0011。
二进制的 ^ 就是在同一个二进制位中,两个相同的数的结果就为0,不同就为1 比如 1100^1011 答案是 0111。
#include <stdio.h> #include <string.h> int n,graph [ 205 ][ 205 ]; void floyd() { for( int k = 1 ; k <= n ; k++ ) for( int i = 1 ; i <= n ; i++ ) for( int j = 1 ; j <= n ; j++ ) graph [ i ][ j ] |= ( graph[ i ][ k ] & graph [ k ][ j ]); } int main() { // freopen("in.txt","r",stdin); while( scanf("%d",&n) , n ) { memset( graph , 0 , sizeof( graph ) ); int a,b; char c[ 30 ]; while( scanf("%d%d",&a,&b) , a || b ) { scanf("%s",c); for(int i = 0 ; i < strlen(c) ; i++ ) graph [ a ][ b ] = graph[ a ][ b ]|(1<<c[ i ]-'a'); } floyd(); while(scanf("%d%d",&a,&b),a||b) { for(char d = 'a' ; d <= 'z' ; d++) if( graph[ a ][ b ] & (1<<d-'a')) printf("%c",d); if( graph [ a ][ b ] == 0) printf("-"); printf("\n"); } printf("\n"); } return 0; }