HDU 5961 傳遞 隨機化

傳遞

題目鏈接:

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

Description

咱們稱一個有向圖G是傳遞的,當且僅當對任意三個不一樣的頂點a,,若G中有 一條邊從a到b且有一條邊從b到c ,則G中一樣有一條邊從a到c。
咱們稱圖G是一個競賽圖,當且僅當它是一個有向圖且它的基圖是徹底圖。換句 話說,將徹底圖每條邊定向將獲得一個競賽圖。
下圖展現的是一個有4個頂點的競賽圖。c++

如今,給你兩個有向圖P = (V,Ep)和Q = (V,Ee),知足:測試

  1. EP與Ee沒有公共邊;
  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。保證輸入的圖必定知足給出的限制條件。spa

Output

對每一個數據,你須要輸出一行。若是P! Q都是傳遞的,那麼請輸出’T’。不然, 請輸出’N’ (均不包括引號)。code

Sample Input

4
4
-PPP
--PQ
---Q
----
4
-P-P
--PQ
P--Q
----
4
-PPP
--QQ
----
--Q-
4
-PPP
--PQ
----
--Q-ip

Sample Output

T
N
T
Nci

Hint

題意

題解:

題目給了賊多的條件,感受好像是很難的問題。get

因而咱們隨機化吧,隨便隨機了一下就過了。input

代碼

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2017;

string s[maxn];
vector<int> E1[maxn];
vector<int> E2[maxn];
int n;
int step;
int check1(){
    step = 1000000;
    for(int i=0;i<step;i++){
        int x = rand()%n+1;
        for(int j=0;j<E1[x].size();j++){
            int v = E1[x][j];
            for(int k=0;k<E1[v].size();k++){
                int z = E1[v][k];
                if(s[x][z]!='P')
                    return 0;
                step--;
                if(step<i)return 1;
            }
        }
    }
    return 1;
}
int check2(){
    step = 1000000;
    for(int i=0;i<step;i++){
        int x = rand()%n+1;
        for(int j=0;j<E2[x].size();j++){
            int v = E2[x][j];
            for(int k=0;k<E2[v].size();k++){
                int z = E2[v][k];
                if(s[x][z]!='Q')
                    return 0;
                step--;
                if(step<i)return 1;
            }
        }
    }
    return 1;
}
void solve(){
    scanf("%d",&n);
    for(int i=0;i<maxn;i++)
        E1[i].clear(),E2[i].clear();
    for(int i=0;i<n;i++)
        cin>>s[i];
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(s[i][j]=='P'){
                E1[i].push_back(j);
            }
        }
    }
    int flag1=check1();
    for(int i=0;i<maxn;i++)
        E1[i].clear(),E2[i].clear();
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(s[i][j]=='Q'){
                E2[i].push_back(j);
            }
        }
    }
    int flag2=check2();
    if(flag1+flag2==2){
        cout<<"T"<<endl;
    }else{
        cout<<"N"<<endl;
    }
}
int main(){
    srand(772002);
    int t;scanf("%d",&t);
    while(t--)solve();
}
相關文章
相關標籤/搜索