[HDU5961] 传递


题目

原题地址

解说

可以总结出\(edge[a] & edge[b] = edge[b]\)
a连得边的集合交上b连的边的集合=b连得边的集合。
处理集合的交集就用\(bitset\)就好了。

代码

#include
using namespace std;
const int  maxn = 2022;
const int maxm = maxn*maxn;
struct node{
    int v,next;
}edge[maxm];
int head[maxn] ,cnt;
int n;
char mp[maxn][maxn];
bitsetb[maxn];
void add_edge(int u,int v){
    edge[cnt].v = v, edge[cnt].next = head[u];
    head[u] = cnt++;
    b[u][v] = 1;
}
bool legal(char ch){
    memset(head,-1,sizeof(head));
    cnt = 0;
    for(int i=1;i<=n;i++) b[i].reset();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(mp[i][j] == ch){
                add_edge(i,j);
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=head[i];j+1;j = edge[j].next){
            int v = edge[j].v;
            if((b[i] & b[v] )!= b[v]) return 0;
        }
    }
    return 1;
}
int main(){
    int t;scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",mp[i] + 1);
        }
        if(legal('P') && legal('Q')){
            printf("T\n");
        }
        else
            printf("N\n");
    }
    return 0;
}

幸甚至哉,歌以咏志。