HDU-5961 传递(暴力)
来源:互联网 发布:好看的武侠小说知乎 编辑:程序博客网 时间:2024/06/06 03:21
传递
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.EP 与Ee 没有公共边;
2. (V,Ep⋃Ee )是一个竞赛图。
你的任务是:判定是否P,Q同时为传递的。
我们称图G是一个竞赛图,当且仅当它是一个有向图且它的基图是完全图。换句 话说,将完全图每条边定向将得到一个竞赛图。
下图展示的是一个有4个顶点的竞赛图。
现在,给你两个有向图P = (V,
1.
2. (V,
你的任务是:判定是否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。保证输入的图一定满足给出的限制条件。
第一行有一个正整数,表示数据的组数。
对于每组数据,第一行有一个正整数n。接下来n行,每行为连续的n个字符,每 个字符只可能是’-’,’P’,’Q’中的一种。
保证1 <= n <= 2016,一个测试点中的多组数据中的n的和不超过16000。保证输入的图一定满足给出的限制条件。
Output
对每个数据,你需要输出一行。如果P! Q都是传递的,那么请输出’T’。否则, 请输出’N’ (均不包括引号)。
Sample Input
44-PPP--PQ---Q----4-P-P--PQP--Q----4-PPP--QQ------Q-4-PPP--PQ------Q-
Sample Output
TNTNHint在下面的示意图中,左图为图为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;}
阅读全文
0 0
- HDU-5961 传递(暴力)
- HDU 5961 传递(暴力枚举)
- Hdu 5961 传递【暴力枚举】
- HDU 5745(暴力)
- HDU 5762(暴力)
- hdu 5762(暴力)
- HDU 5961 传递(BFS)
- HDU 5961 传递(BFS)
- 洛谷 2661 信息传递(暴力、tarjan)
- hdu 1015 (DFS,暴力)
- hdu 4968(暴力枚举)
- HDU 5258(水暴力)
- hdu 5305 Friends(暴力)
- hdu 5353 Average(暴力)
- hdu 5339 Untitled(暴力)
- hdu 5386 Cover (暴力)
- hdu 5386 Cover(暴力)
- hdu 5492 (暴力+nice)
- 【POJ2001】Shortest Prefixes
- JS学习(13)----eventlistener
- RAID介绍
- 分解质因数(5分)
- MyBatis错题分析
- HDU-5961 传递(暴力)
- springMVC 请求404错误或静态资源无法访问
- C++开源大全
- 如何关闭账号自动同步?
- iOS 崩溃记录
- Linux上Scala的安装
- git
- JavaScript获取form表单中的数据以及拼接传参
- POJ