HDU 5961 传递

HDU 5961 传递

题目大意

我们称一个有向图G是传递的,当且仅当对任意三个不同的顶点a,若G中有一条边从a到b且有一条边从b到c ,则G中同样有一条边从a到c。
我们称图G是一个竞赛图,当且仅当它是一个有向图且它的基图是完全图。换句话说,将完全图每条边定向将得到一个竞赛图。
下图展示的是一个有4个顶点的竞赛图。

solution

拓扑排序找环
只有a->b,b->c,一定存在a->c,那么就很容易处理了,只要把a连接的所有点标记掉,那如果图是传递的,就不存在其他点能通过a连接的点到达,反之图就不是传递的,即如果bfs搜到了长度超过1的路径,就意味着图不是传递的。

代码YouXam

#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
std::vector<int> edge[2017];
std::queue<int> Q;
int m, n, in[2017], cnt, newn;
int main() {
    scanf("%d", &n);
    while (n--) {
        scanf("%d", &m);
        memset(in, 0, sizeof(in));
        for (int i = 1; i <= m; i++) edge[i].clear();
        while (!Q.empty()) Q.pop();
        for (int i = 1; i <= m; ++i)
            for (int j = 1; j <= m; ++j) {
                char ch;
                scanf(" %c", &ch);
                if (ch == 'P') in[j]++, edge[i].push_back(j);
                else if (ch == 'Q') in[i]++, edge[j].push_back(i);
            }
        for (int i = 1; i <= m; i++) if (!in[i]) Q.push(i);
        cnt = 0;
        while (!Q.empty()) {
            newn = Q.front(), Q.pop(), cnt++;
            for (int i = 0; i < edge[newn].size(); i++) {
                in[edge[newn][i]]--;
                if (in[edge[newn][i]] == 0) Q.push(edge[newn][i]);
            }
        }
        puts((cnt == m)?"T":"N");
    }
}
原文地址:https://www.cnblogs.com/rui-4825/p/12927115.html