HDU-5961 传递(暴力)

el/2024/3/2 11:02:54


传递

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1140    Accepted Submission(s): 514


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

现在,给你两个有向图P = (V,Ep)和Q = (V,Ee),满足:
1.   EPEe没有公共边;
2.  (V,EpEe)是一个竞赛图。
你的任务是:判定是否P,Q同时为传递的。


Input
包含至多20组测试数据。
第一行有一个正整数,表示数据的组数。
对于每组数据,第一行有一个正整数n。接下来n行,每行为连续的n个字符,每 个字符只可能是’-’,’P’,’Q’中的一种。
如果第i行的第j个字符为’P’,表示有向图P中有一条边从i到j;
如果第i行的第j个字符为’Q’,表示有向图Q中有一条边从i到j;
否则表示两个图中均没有边从i到j。
保证1 <= n <= 2016,一个测试点中的多组数据中的n的和不超过16000。保证输入的图一定满足给出的限制条件。

Output
对每个数据,你需要输出一行。如果P! Q都是传递的,那么请输出’T’。否则, 请输出’N’ (均不包括引号)。

Sample Input
4 4 -PPP --PQ ---Q ---- 4 -P-P --PQ P--Q ---- 4 -PPP --QQ ---- --Q- 4 -PPP --PQ ---- --Q-

Sample Output
T N T N
Hint
在下面的示意图中,左图为图为Q。
注:在样例2中,P不是传递的。在样例4中,Q不是传递的。
题解:暴力

如果u是v的父节点,v是w的父节点,那么u一定也是w的父节点,用bitset记录每个点的父节点有哪些,跑一遍spfa,最后枚举每个点的父节点看是否与父节点连上了一条边


#include<bits/stdc++.h>
using namespace std;
const int MX = 2020;
char mp[MX][MX];
bitset<MX>b[MX];
struct Edge {int v, nxt;
} E[MX*MX], edge[MX*MX];
int head[MX], Head[MX], tot, rear, n;
int p[MX], p1[MX], p2[MX], vis[MX];
void init() {memset(head, -1, sizeof(head));memset(Head, -1, sizeof(Head));for (int i = 0; i < n; i++) p1[i] = p2[i] = i;tot = rear = 0;
}
void ADD(int u, int v) {E[tot].v = v;E[tot].nxt = Head[u];Head[u] = tot++;
}
void add(int u, int v) {edge[rear].v = v;edge[rear].nxt = head[u];head[u] = rear++;
}
int find(int x) {return p[x] == x ? x : (p[x] = find(p[x]));
}
int find1(int x) {return p1[x] == x ? x : (p1[x] = find1(p1[x]));
}
int find2(int x) {return p2[x] == x ? x : (p2[x] = find2(p2[x]));
}
bool solve(Edge E[], int head[], int px[], char op) {for (int i = 0; i < n; i++) {b[i].reset();b[i][i]=1;vis[i] = 0;p[i] = px[i];}queue<int>q;for (int i = 0; i < n; i++) if (find(i) == i) {q.push(i); vis[i] = 1;}while (!q.empty()) {int u = q.front(); q.pop();vis[u] = 0;for (int i = head[u]; ~i; i = E[i].nxt) {int v = E[i].v;if ((b[v] | b[u]) != b[v]) {b[v] |= b[u];if (!vis[v]) {q.push(v);vis[v] = 1;}}}}for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (i == j) continue;if (b[i][j] && mp[j][i] != op) return false;}}return true;
}
int main() {int T;//freopen("in.txt","r",stdin);scanf("%d", &T);while (T--) {scanf("%d", &n);init();for (int i = 0; i < n; i++) scanf("%s", &mp[i]);for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if (mp[i][j] == 'P') {ADD(i, j);int pi = find1(i), pj = find1(j);if (pi != pj) p1[pj] = pi;}if (mp[i][j] == 'Q') {add(i, j);int pi = find2(i), pj = find2(j);if (pi != pj) p2[pj] = pi;}}}if (solve(E, Head, p1, 'P') && solve(edge, head, p2, 'Q')) printf("T\n");else printf("N\n");}return 0;
}




http://www.ngui.cc/el/2314428.html

相关文章

Splay树

作者:Dong | 新浪微博&#xff1a;西成懂 | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明 网址:http://dongxicheng.org/structure/splay-tree/ 1、 概述 二叉查找树&#xff08;Binary Search Tree&#xff0c;也叫二叉排序树&#xff0c;即Binary S…

HDU-6038 Function(思维)

传送门&#xff1a;点这里~ 首先将A,B序列划分成若干循环节 循环节的定义是&#xff1a;Axy,Ayz,Azx类似于这样的循环对应关系 为什么要找出A的循环节呢&#xff1f; 首先看样例&#xff1a;f[0]B[f[A[0]]]B[f[1]], f[1]B[f[A[1]]]B[f[0]], f[2]B[f[A…

HDU-6044 Limited Permutation(计数)

传送门&#xff1a;点这里~题意&#xff1a;对于有n个元素的全排列的合法性定义为&#xff1a;有n个区间&#xff0c;对于第i个区间[li,ri]有li<i<ri,对于任意1<L<i<R<n&#xff0c;当前仅当li<L<i<R<ri时P[i]min(P[L],P[L1],...,P[R])。现在给出…

HDU-6040 Hints of sd0061(线性找第k小)

传送门&#xff1a;HDU-6040 题意&#xff1a;给出n个数字&#xff0c;由m次查询&#xff0c;第i次查询问第b[i]小的数是多少 题解&#xff1a;线性找第k小 用到一个STL nth_element(A, A k, An) 表示在数组A的[0,n-1]中找到第k小的并放在第k个位置&#xff0c;并且前k-1个…

HDU-6041 I Curse Myself(双连通分量+k路归并)

传送门&#xff1a;HDU-6041 题解&#xff1a;这个图是仙人掌&#xff0c;因此要形成生成树&#xff0c;每个环都得去掉一条边&#xff0c;因此可以将每个环上的边权值看成一个集合&#xff0c;要求每一个集合中选一个数加起来&#xff0c;求所有和中前k大的为多少&#xff0c…

HDU-6039 Gear Up(线段树+DFS序)

传送门&#xff1a;HDU-6039 题意&#xff1a;n个齿轮&#xff0c;有m(m<n)条边&#xff0c;有两种连接方式&#xff1a; ①2齿轮共轴&#xff0c;这时角速度相等 ②2齿轮共边&#xff0c;这时线速度相等 每对齿轮最多只有一种连接方式 现在给出2种操作&#xff1a; ①修改…

HDU-6048 Puzzle(思维题)

传送门&#xff1a;HDU-6048 又是一道结论题&#xff08;吐槽&#xff1a;这次多校好多结论题啊&#xff09; 根据九宫格问题的结论&#xff1a;将矩阵中的数按从上到下从左到右排成一列&#xff0c;其逆序对如果为偶数则一定有解&#xff0c;否则一定无解 求逆序对的方法&a…

HDU-6052 To my boyfriend(单调栈)

传送门&#xff1a;HDU-6052 对于每种颜色我们考虑它对答案的贡献&#xff0c;因为一种颜色可能会有多个方格&#xff0c;在计算某个方格的贡献时&#xff0c;与它相同颜色且被计算过的方格是不能考虑的&#xff0c;这时可以把这些方格当做障碍物。 具体做法是&#xff1a;设…

HDU-6046 hash(哈希)

传送门&#xff1a;HDU-6046 多校赛的时候根本不知道如何下手&#xff0c;怎么算复杂度都是爆表的&#xff0c;根据题解说复杂度是O(1e3^2*64)&#xff0c;感觉好像是这个道理&#xff0c;于是就用HashMap的模板敲了一遍&#xff0c;结果还真的过了&#xff08;比标程快了一倍…

HDU-4649 Professor Tian(期望dp)

传送门&#xff1a;HDU-4649 题意&#xff1a;给你一个式子A0O1A1O2A3....OnAn&#xff0c;第i位有pi的概率消失掉&#xff0c;要计算式子最后值的期望题解&#xff1a;期望dp每个数二进制最多20位&#xff0c;我们维护每一位取0或取1的情况的概率&#xff0c;最后把为1的概率乘…