Codeforces Round 925 (Div. 3) F. Chat Screenshots【拓扑排序找环】

原题链接:https://codeforces.com/problemset/problem/1931/F

题意翻译

给出 n 个人进行的聊天室中,k 个人做的截图,每个截图中截图者都在第一位置,其后各位按照发帖时间前后确定。判断这些聊天室截图是否自洽(即能确定至少一种可能的发帖顺序)。

输入

第一行包含一个整数 t ( 1≤t≤10^4 ) - 输入测试用例的数量。下面是测试用例的说明。

每个测试用例描述的第一行包含两个整数 n 和 k ( 1≤k≤n≤2⋅10^5,n⋅k≤2⋅10^5 )--聊天参与者人数和发布屏幕截图的参与者人数。

接下来的 k 行包含参与者发布的截图描述。

第 i 行包含 n 个整数 aij ( 1≤aij≤n ,所有 aij 都是不同的)--参与者显示给参与者 ai0 的顺序,其中 ai0 --截图的作者。您可以在截图描述中将其显示在列表顶部。

保证所有测试用例的 n⋅k 总和不超过 2⋅10^5 。还可以保证所有截图的作者都是不同的。

输出

输出 t 行,每一行都是相应测试用例的答案。如果至少存在一种参与者顺序,可以获得所有 k 截图,则输出 "是"。否则,输出 "否"。

您可以用任何大小写(大写或小写)输出答案。例如,字符串 "yEs"、"yes"、"Yes "和 "YES "将被视为肯定回答。

输入输出样例
输入 
10
5 1
1 2 3 4 5
4 4
1 2 3 4
2 3 1 4
3 2 1 4
4 2 3 1
6 2
1 3 5 2 4 6
6 3 5 2 1 4
3 3
1 2 3
2 3 1
3 2 1
10 2
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
1 1
1
5 2
1 2 3 5 4
2 1 3 5 4
3 3
3 1 2
2 3 1
1 3 2
5 4
3 5 1 4 2
2 5 1 4 3
1 5 4 3 2
5 1 4 3 2
3 3
1 3 2
2 1 3
3 2 1
输出 
YES
YES
YES
YES
NO
YES
YES
YES
YES
NO

解题思路:

对于每张截图,第一个位置是作者自己不需要考虑,除了第一个元素之外后面的元素的先后顺序可以根据截图确定,对于每一张截图,我们从第二个位置开始分析,那么第二个位置的应该在第三个位置前面,我们可以从第二个位置向第三个位置连一条边,同理第三个位置可以向第四个位置连一条边,后面依此类推,注意第二个位置向第四个位置连边是没有必要的,因为2->3并且3>4那么根据传递性2和4先后顺序也就确定了,所以对于这样的中间边是没有意义的,连这些边反而会导致时间和空间复杂度都变的非常高,所以我们对于每张截图,只需要从第二个位置开始,每一个位置向当前位置的后一个位置连一条有向边即可,那么题目要求的就是是否存在一种顺序使得所有截图除去第一个位置的先后顺序都被满足,那么就是将所有边连上之后会形成一个有向图,问有向图是否存在一个拓扑序,也就是判断是否有环,如果存在一个拓扑序没有环输出YES,否则说明不是拓扑序有环输出NO,对于判断是否有环直接使用拓扑排序处理即可。

时间复杂度:拓扑排序O(n),输入k张截图,每张n个数O(n*k),最终时间复杂度O(n*k)。

空间复杂度:O(n)。

cpp代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;
const int N=2e5+10;
typedef long long LL;

int T,n,k;
int a[N];
int h[N],e[N],ne[N],idx;
int q[N],d[N];
void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

bool top_sort()
{
    int hh=0,tt=-1;
    for(int i=1;i<=n;i++)
        if(!d[i])q[++tt]=i;
    
    while(hh<=tt)
    {
        auto t=q[hh++];
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(--d[j]==0){
                q[++tt]=j;
            }
        }
    }

    return tt==n-1;
}
void solve()
{
    cin>>n>>k;
    for(int i=0;i<=n;i++)h[i]=-1,d[i]=0;
    idx=0;
    for(int i=0;i<k;i++)
    {
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=2;i<n;i++)add(a[i],a[i+1]),d[a[i+1]]++;  //每一张截图从第二个位置开始连边
    }
    if(top_sort())cout<<"YES"<<'\n';  //拓扑排序判断是否有环
    else cout<<"NO"<<'\n';
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>T;
    while(T--)
    {
        solve();
    }
    return 0;
}
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值