ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【CF117C】Cycle

2021-05-12 15:35:31  阅读:200  来源: 互联网

标签:连边 那么 一个点 int CF117C 这条 大小 Cycle


题目

题目链接:https://codeforces.com/contest/117/problem/C
给定一张竞赛图,求任意一个大小为 \(3\) 的环。
\(n\leq 5000\)。

思路

给出一种非常简洁的做法。
考虑对于一个点 \(x\),我们能找到两个点 \(y,z\),满足它们之间的连边如下:

那么 \(x\to z\) 这条边一定是没用的,也就是如果我们能找到一个大小为 \(3\) 的环包含 \(x\to z\) 这条边,那么我们一定可以找出另一个不包含 \(x\to z\) 这条边的大小为 \(3\) 的环。如下图

假设 \(z,a,x\) 三个点形成了一个大小为 \(3\) 的环,那么考虑 \(a\) 和 \(y\) 之间的连边,如果是 \(a\to y\),那么 \(a,y,z\) 三个点可以形成另一个环;如果是 \(y\to a\),那么 \(a,x,y\) 三个点可以形成另一个环。
所以我们可以直接把 \(x\to z\) 这条边忽略掉。
这样的话把若干条边忽略后,每一个点最多只有一条出边。那么我们只需要枚举两个点 \(i,j\),再判断 \(i,\text{to}_i,j\) 三点是否形成环即可。
时间复杂度 \(O(n^2)\),代码仅有 459B。

代码

#include <bits/stdc++.h>
using namespace std;

const int N=5010;
int n,to[N];
char a[N][N];

int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%s",a[i]+1);
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
			if (a[i][j]==49 && (!to[i] || a[j][to[i]]==49)) to[i]=j;
	for (int i=1;i<=n;i++)
		for (int j=1;j<=n;j++)
			if (a[to[i]][j]==49 && a[j][i]==49)
				return printf("%d %d %d\n",i,to[i],j),0;
	printf("-1");
	return 0;
}

标签:连边,那么,一个点,int,CF117C,这条,大小,Cycle
来源: https://www.cnblogs.com/stoorz/p/14759921.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有