1 条题解

  • 0
    @ 2025-8-24 22:01:34

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar ix35
    垒球

    搬运于2025-08-24 22:01:34,当前版本为作者最后更新于2020-02-04 19:45:09,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    大致思路就是:如果在图 D 中:uvwu\to v\to w,又有 xvwx\to v\to w,那么在 E 中,uvuvxvxv 都向 vwvw 连边。此时如果存在另一个 yy 使得 vyv\to y 有边,则在 E 中 uvuvxvxv 都应该向 vyvy 有边。

    也就是说,两个点指向一个公共的点,那么它们所有出边指向的点集必然相同,事实上这是存在 D 的充要条件,证明不难。

    之前几篇题解要么用了并查集,要么用了数组暴力判断,这里提供一种不难想且速度不慢的方法:Bitset。

    用 Bitset 记录邻接矩阵,枚举两行,算一下两行的与和异或,如果与不为 00,则说明指向公共点,此时再看异或,如果异或不为 00,说明出边不重合,答案为 No.

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=310;
    int t,n,m,x,y;
    bitset <MAXN> b[MAXN],tmp1,tmp2;
    int main () {
    	scanf("%d",&t);
    	for (int ii=1;ii<=t;ii++) {
    		scanf("%d%d",&n,&m);
    		for (int i=1;i<=n;i++) {b[i].reset();}
    		for (int i=1;i<=m;i++) {
    			scanf("%d%d",&x,&y);
    			x++,y++;
    			b[x].set(y);
    		}
    		int flg=0;
    		for (int i=1;i<=n;i++) {
    			if (flg) {break;}
    			for (int j=1;j<=n;j++) {
    				tmp1=b[i]&b[j],tmp2=b[i]^b[j];
    				if (tmp1.count()!=0&&tmp2.count()!=0) {flg=1;break;}
    			}
    		}
    		printf("%s\n",flg?"No":"Yes");
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    3558
    时间
    500ms
    内存
    63MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者