HDU - 5961 传递 想法,bfs

题意:给你一个有向图,满足去掉方向是完全图,将其拆成PQ两个图(没有公共边),问你两图是否分别满足对于任意3个点a,b,c 若有一条边从a到b且有一条边从b到c ,则同样有一条边从a到c。 

题解:观察,发现题目等价于对PQ分别bfs。如果某点的深度大于等于2就判错。用vis储存深度,注意对vis数组的操作:每推入一个起点时,vis[起点]=1,(pop时不--,最后统一memset0)每推入一个未访问的相邻点v时vis[v]=vis[now]+1;

坑:1.cin>>n写错地方,结果写了两个cin>>n,结果把图的第一个符吞了。2.q.clear没有这个函数,用赋值 q1 = queue<int>();3.用邻接链表建图遍历边时循环从0开始

 

ac代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
const int maxn = 2020;
vector<int> EP[maxn],EQ[maxn];
char map[maxn][maxn];
int vis[maxn];
int main() {
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++) {
            EP[i].clear();
            EQ[i].clear();
    }
        
        for (int i = 1; i <= n; i++) {
            scanf("%s", map[i]+1);
            //cout << map[i] << endl;
            
            for (int j =1; j < n; j++) {
                if (map[i][j] == 'P')EP[i].push_back(j);
                if (map[i][j] == 'Q') EQ[i].push_back(j);
            }        
        }
        //for (int i = 1; i <= n; i++)cout << map[i]<<endl;
        //bfs();
        int flag = 1;
        queue<int> Q;
        for (int i = 1; i <= n; i++) {
            if (EP[i].empty()) continue;
            memset(vis, 0, sizeof(vis));
            
            Q.push(i); vis[i] = 1;
            while (!Q.empty()) {
                int now = Q.front();
                Q.pop(); //vis[now]--;
                for (int j = 0; j < EP[now].size(); j++) {
                    int v = EP[now][j];
                    if (!vis[v]) {
                        vis[v]=vis[now]+1;
                        Q.push(v);
                    }
                    if (vis[v] == 3) {
                        flag = 0;
                        break;    
                    }
                    

                }
            }
            if (flag == 0)break;
        }
        if (!flag) {
            puts("N");
            continue;
        }
        //repeat;
         flag = 1;
         while (!Q.empty()) Q.pop();
        for (int i = 1; i <= n; i++) {
            if (EQ[i].empty()) continue;
            memset(vis, 0, sizeof(vis));

            Q.push(i); vis[i] = 1;
            while (!Q.empty()) {
                int now = Q.front();
                Q.pop(); //vis[now]--;
                for (int j = 0; j < EQ[now].size(); j++) {
                    int v = EQ[now][j];
                    if (!vis[v]) {
                        vis[v] = vis[now] + 1;
                        Q.push(v);
                    }
                    if (vis[v] == 3) {
                        flag = 0;
                        break;
                    }


                }
            }
            if (flag == 0)break;
        }
        if (!flag) puts("N");    
        else puts("T");

    }
}

 

posted @ 2018-03-15 16:34  SuuTTT  阅读(158)  评论(0编辑  收藏  举报