HDU5961 传递 (随机化 || 暴力 || 正解)

本文深入解析HDU-5961竞赛题,介绍随机化、暴力与正解三种策略。通过随机检验连通性,使用BFS或Floyd优化,最终利用PQ图合并判环验证。代码示例丰富,适合算法学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 HDU - 5961    <-题目链接

 

思路:

思路1:随机化

这题不能随机答案并输出,20组数据几率还是太小了点。

我们想,它是个完全图,又是单向的,数据生成应该也不太好构造,2000*2000呢,所以我们想是不是可以随机化水一水。

srand(time(NULL));

每次随机三个数,然后我们检验这三个数的连通性。这个随机不一定是对的,因为最终图里可能只有一个小区域不符合连通性,所以我们多随机几次,我取的是400W次,交了两次过了。赛后100W交了3次过了。

check部分:

bool check(int x,int y,int z)
{
	if(mapp[x][y] && mapp[y][z] && !mapp[x][z])	{return false;}
	if(mapp[z][y] && mapp[y][x] && !mapp[z][x])	{return false;}
	
	if(mapp[x][z] && mapp[z][y] && !mapp[x][y])	{return false;}
	if(mapp[y][z] && mapp[z][x] && !mapp[y][x])	{return false;}

	if(mapp[y][x] && mapp[x][z] && !mapp[y][z])	{return false;}
	if(mapp[z][x] && mapp[x][y] && !mapp[z][y])	{return false;}

	if(mapq[x][y] && mapq[y][z] && !mapq[x][z])	{return false;}
	if(mapq[z][y] && mapq[y][x] && !mapq[z][x])	{return false;}

	if(mapq[x][z] && mapq[z][y] && !mapq[x][y])	{return false;}
	if(mapq[y][z] && mapq[z][x] && !mapq[y][x])	{return false;}

	if(mapq[y][x] && mapq[x][z] && !mapq[y][z])	{return false;}
	if(mapq[z][x] && mapq[x][y] && !mapq[z][y])	{return false;}

	return true;
}

随机化部分:

        bool flag = 1;
		for(int i = 1;i <= 4000000;i ++)
		{
			int x = rand()%n+1;
			int y = rand()%n+1;
			while(y == x)	y = rand()%n+1;
			int z = rand()%n+1;
			while(z == x || z == y)	z = rand()%n+1;
			if(!check(x,y,z))
			{
			//	printf("x,y,z : %d %d %d\n",x,y,z);
				flag = 0;
				break;
			}
		}
		if(flag)	printf("T\n");
		else	printf("N\n");

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<ctime>
#define up(i,x,y) for(int i = x;i <= y;i ++)
#define down(i,x,y) for(int i = x;i >= y;i --)
#define mem(a,b) memset((a),(b),sizeof(a))
#define mod(x) ((x)%MOD)
#define lson p<<1
#define rson p<<1|1
using namespace std;
typedef long long ll;
const int SIZE = 2020;
const int INF = 2147483640;
const double eps = 1e-8;

inline void RD(int &x)
{
    x = 0;  char c; c = getchar();
    bool flag = 0;
    if(c == '-')    flag = 1;
    while(c < '0' || c > '9')   {if(c == '-')   {flag = 1;} c = getchar();}
    while(c >= '0' && c <= '9') x = (x << 1) + (x << 3) + c - '0',c = getchar();
}
int t;
char maps[SIZE][SIZE];
bool mapp[SIZE][SIZE],mapq[SIZE][SIZE];

bool check(int x,int y,int z)
{
	if(mapp[x][y] && mapp[y][z] && !mapp[x][z])	{return false;}
	if(mapp[z][y] && mapp[y][x] && !mapp[z][x])	{return false;}
	
	if(mapp[x][z] && mapp[z][y] && !mapp[x][y])	{return false;}
	if(mapp[y][z] && mapp[z][x] && !mapp[y][x])	{return false;}

	if(mapp[y][x] && mapp[x][z] && !mapp[y][z])	{return false;}
	if(mapp[z][x] && mapp[x][y] && !mapp[z][y])	{return false;}

	if(mapq[x][y] && mapq[y][z] && !mapq[x][z])	{return false;}
	if(mapq[z][y] && mapq[y][x] && !mapq[z][x])	{return false;}

	if(mapq[x][z] && mapq[z][y] && !mapq[x][y])	{return false;}
	if(mapq[y][z] && mapq[z][x] && !mapq[y][x])	{return false;}

	if(mapq[y][x] && mapq[x][z] && !mapq[y][z])	{return false;}
	if(mapq[z][x] && mapq[x][y] && !mapq[z][y])	{return false;}

	return true;
}
int main(int argc, char const *argv[])
{
	//qaqaqqaqqaq
	srand(time(NULL));
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		for(int i = 1;i <= n;i ++)	scanf("\n%s",maps[i]+1);
		for(int i = 1;i <= n;i ++)
		{
			for(int j = 1;j <= n;j ++)
			{
				if(maps[i][j] == 'P')	mapp[i][j] = 1;
				else	mapp[i][j] = 0;
				if(maps[i][j] == 'Q')	mapq[i][j] = 1;
				else	mapq[i][j] = 0;
			}
		}
		bool flag = 1;
		for(int i = 1;i <= 4000000;i ++)
		{
			int x = rand()%n+1;
			int y = rand()%n+1;
			while(y == x)	y = rand()%n+1;
			int z = rand()%n+1;
			while(z == x || z == y)	z = rand()%n+1;
			if(!check(x,y,z))
			{
			//	printf("x,y,z : %d %d %d\n",x,y,z);
				flag = 0;
				break;
			}
		}
		if(flag)	printf("T\n");
		else	printf("N\n");
	}
	return 0;
}
/*
1
4
-PPP
--QQ
----
--Q-
*/

方法2:暴力

暴力1:floyd优化。没看= = 有人这么写的。

暴力2:BFS层次。对每个点BFS,如果有深度大于1的儿子则是不满足的,最终如果都深度为1,则满足。

虽然跑的很快但我觉得还是很像暴力。。


方法3:正解

给定的图是个竞赛图且两图没有公共边。这就让我们疑惑这个性质到底怎么用?

正确的用法是,将PQ合并判环,再将P(~Q)合并判环,最终如果都没有则满足题目条件。

证明:一句话,不满足连通性的条件一定是a->b,b->c,而不存在a->c,又因为是完全图,那么另一条边一定在Q图里,但是方向未知,不过反正就只有两个方向,枚举两个方向,肯定有一个有环,有环就不满足条件。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值