其他分享
首页 > 其他分享> > poj2570 Fiber Network(floyed传递闭包 + 二进制压缩)

poj2570 Fiber Network(floyed传递闭包 + 二进制压缩)

作者:互联网

题意:        

       有一个有向图,对于有向图的每条边上有一个公司名字的集合,代表该集合内的公司能提供该边的连通服务.现在我们给你q个查询.对于每个查询a和b,你要回答有哪些公司能提供从a到b的通路服务.。

思路:题意就是给你一个起点a,终点b。然后让你输出a->b路上的公共字符。这算是一种集合关系,相同线路取交集,不同线路取并集,显然用二进制存储更加方便,26个字符对应着二进制中 0 ~25位。压缩完边之后,用floyed传递一下,最后用lowbit不断出最后一位就可以了。

AC Code:

#include<iostream>
#include<map>
#include<cstdio>
#include<string>
#include<cstring>
#include<sstream>
using namespace std;
int w[205][205];
int n,m;
map<int,int > st;
void floyed()
{
    for(int k = 1;k <= n; ++k)
       for(int i = 1;i <= n; ++i)
         for(int j = 1;j <= n; ++j)
          w[i][j] = w[i][j] |  (w[i][k] & w[k][j]);
}
int lowbit(int x)
{
    return x&(-x);
}
int main()
{
    //freopen("input.txt","r",stdin);
    for(int i = 'a' - 'a';i<='z' - 'a';++i)//打表,预处理lowbit对应1在哪一位
    {
        st[1<<i] = i;
    }
    string s1,s2;
    int f,t;
    while(cin>>n&&n)
    {
        memset(w,0,sizeof(w));
        while(cin>>f>>t&&f+t)
        {
            cin>>s1;
            stringstream ss(s1);
            char c;
            while(ss>>c)
            {
                w[f][t] |= 1<<(c - 'a');//将边压缩
            }
        }
        floyed();
        while(cin>>f>>t&&f+t)
        {
            int tmp = w[f][t];
            if(tmp==0) cout<<'-'<<endl;
            else {
                while(tmp){
                    int idx = lowbit(tmp);
                    cout<<char('a' + st[idx]);
                    tmp -= idx;
                }
                puts("");
            }
        }
        cout<<endl;
    }
}

 

标签:闭包,poj2570,Fiber,题意,floyed,int,二进制,&&,include
来源: https://blog.csdn.net/qq_43408238/article/details/100107626