首页 > 代码库 > HDU 5961 传递 【图论+拓扑】 (2016年中国大学生程序设计竞赛(合肥))

HDU 5961 传递 【图论+拓扑】 (2016年中国大学生程序设计竞赛(合肥))

传递

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
 
 

 

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

现在,给你两个有向图P = (V,Ep)和Q = (V,Ee),满足:
1.   EPEe没有公共边;
2.  (V,Ep?Ee)是一个竞赛图。
你的任务是:判定是否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不是传递的。
 

 

Source
2016年中国大学生程序设计竞赛(合肥)-重现赛(感谢安徽大学)
 

 

Recommend
jiangzijing2015   |   We have carefully selected several similar problems for you:  5981 5980 5979 5978 5977 
 

 

Statistic | Submit | Discuss | Note

 

 

题目链接:

  http://acm.hdu.edu.cn/showproblem.php?pid=5961

题目大意:

  一张竞赛图(完全图每条边给方向)拆成两个子图P和Q,判断P和Q是否同时满足传递性。

题目思路:

  【拓扑】

  PUQ为完全图。根据竞赛图的性质,若P或Q中有环则不满足传递(无自环)

  若P中a->b,b->c,而a不到c,则a和c之间的边在Q中。那么PUQ或PUQ‘(Q‘为Q的反图)中一定存在环a->b,b->c,c->a。

  所以只需要分别求PUQ和PUQ‘中之一是否有环即可,有环不传递。所以用拓扑排序判断是否有环

  

技术分享
  1 //
  2 //by coolxxx
  3 //#include<bits/stdc++.h>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<string>
  7 #include<iomanip>
  8 #include<map>
  9 #include<stack>
 10 #include<queue>
 11 #include<set>
 12 #include<bitset>
 13 #include<memory.h>
 14 #include<time.h>
 15 #include<stdio.h>
 16 #include<stdlib.h>
 17 #include<string.h>
 18 //#include<stdbool.h>
 19 #include<math.h>
 20 #pragma comment(linker,"/STACK:1024000000,1024000000")
 21 #define min(a,b) ((a)<(b)?(a):(b))
 22 #define max(a,b) ((a)>(b)?(a):(b))
 23 #define abs(a) ((a)>0?(a):(-(a)))
 24 #define lowbit(a) (a&(-a))
 25 #define sqr(a) ((a)*(a))
 26 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
 27 #define mem(a,b) memset(a,b,sizeof(a))
 28 #define eps (1e-8)
 29 #define J 10000
 30 #define mod 2147493647
 31 #define MAX 0x7f7f7f7f
 32 #define PI 3.14159265358979323
 33 #define N 2024
 34 #define M 2031124
 35 using namespace std;
 36 typedef long long LL;
 37 double anss;
 38 LL aans;
 39 int cas,cass;
 40 int n,m,lll,ans;
 41 int in[N],last[N];
 42 bool u[N];
 43 char s[N][N];
 44 struct xxx
 45 {
 46     int next,to;
 47 }e[M];
 48 void add(int x,int y)
 49 {
 50     e[++lll].next=last[x];
 51     e[lll].to=y;
 52     last[x]=lll;
 53 }
 54 void tuopu()
 55 {
 56     int i,now,to;
 57     ans=0;
 58     queue<int>q;
 59     for(i=1;i<=n;i++)
 60         if(!in[i])
 61         {
 62             u[i]=1;ans++;
 63             q.push(i);
 64         }
 65     while(!q.empty())
 66     {
 67         now=q.front();q.pop();
 68         for(i=last[now];i;i=e[i].next)
 69         {
 70             to=e[i].to;
 71             if(u[to])continue;
 72             if(!(--in[to]))
 73             {
 74                 u[to]=1;ans++;
 75                 q.push(to);
 76             }
 77         }
 78     }
 79 }
 80 int main()
 81 {
 82     #ifndef ONLINE_JUDGE
 83     freopen("1.txt","r",stdin);
 84 //    freopen("2.txt","w",stdout);
 85     #endif
 86     int i,j,k;
 87     int x,y,z;
 88 //    init();
 89     for(scanf("%d",&cass);cass;cass--)
 90 //    for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
 91 //    while(~scanf("%s",s))
 92 //    while(~scanf("%d%d",&n,&m))
 93     {
 94         lll=0;mem(in,0);mem(last,0);mem(u,0);
 95         scanf("%d",&n);
 96         for(i=1;i<=n;i++)
 97             scanf("%s",s[i]+1);
 98         for(i=1;i<=n;i++)
 99         {
100             for(j=1;j<=n;j++)
101             {
102                 if(s[i][j]==P)
103                     add(i,j),in[j]++;
104                 else if(s[i][j]==Q)
105                     add(i,j),in[j]++;
106             }
107         }
108         tuopu();
109         if(ans<n){puts("N");continue;}
110         lll=0;mem(in,0);mem(last,0);mem(u,0);
111         for(i=1;i<=n;i++)
112         {
113             for(j=1;j<=n;j++)
114             {
115                 if(s[i][j]==P)
116                     add(i,j),in[j]++;
117                 else if(s[i][j]==Q)
118                     add(j,i),in[i]++;
119             }
120         }
121         tuopu();
122         if(ans<n)puts("N");
123         else puts("T");
124     }
125     return 0;
126 }
127 /*
128 //
129 
130 //
131 */
View Code

 

HDU 5961 传递 【图论+拓扑】 (2016年中国大学生程序设计竞赛(合肥))