牛客网第八场 :E Touring cities 求哈密尔顿回路

本文探讨了一个关于在带有额外航线的网格状城市布局中,寻找遍历所有城市至少一次所需的最少天数的问题。该问题涉及到图论中的哈密尔顿回路概念,并通过黑白染色的方法来判断可行解的存在性。

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

标题:E、Touring cities | 时间限制:2秒 | 内存限制:256M

Niuniu wants to tour the cities in Moe country. Moe country has a total of n*m cities. The positions of the cities form a grid with n rows and m columns. We represent the city in row x and column y as (x,y). (1 ≤ x ≤ n,1 ≤ y ≤ m) There are bidirectional railways between adjacent cities. (x1,y1) and (x2,y2) are called adjacent if and only if |x1-x2|+|y1-y2|=1. There are also K bidirectional air lines between K pairs of cities. It takes Niuniu exactly one day to travel by a single line of railway or airplane. Niuniu starts and ends his tour in (1,1). What is the minimal time Niuniu has to travel between cities so that he can visit every city at least once?

Note that the air line may start and end in the same city.

输入描述:

The first line contains oneinteger T(T≤20), which means the number of test cases.

Each test case has the format as described below.

n m K

ax1 ay1 bx1 by1
ax2 ay2 bx2 by2

axK ayK bxK byK

(0 ≤ K ≤ 10. 2 ≤ n,m ≤ 100, 1 ≤ n*m ≤ 100)

There is one bidirectional air line between (axi,ayi) and (bxi,byi). (1 ≤ axi,bxi ≤ n , 1 ≤ ayi,byi ≤ m)

 

输出描述:

For each test case,print one number in a single line, which is the minimal number of days Niuniu has to travel between cities so that he can visit every city at least once.

 

备注:

The air line may start and end in the same city.

示例1

输入

3
2 2 1
1 1 2 2
3 3 1
1 1 3 3
3 3 0

输出

4
9
10

题意 给一个矩形图矩阵中的每个点都可以到达与它相邻的点 上下左右 ,k个双向新航线连接两个点,问能否从(1,1)出发并回到(1,1)并且经过每个点至少一次,求出最短的路径

题解 首先发现任意一个有偶数个点的矩阵都可以n*m的距离完成,奇数个矩阵就不好搞了,在此引用一下官方题解

 

如果nm都是奇数:

将棋盘黑白染色,规定左上角的格子是黑色。那么存在哈密尔顿回路的条件是当且仅当新增的边连接了两个不同的黑色格子。

考虑证明:

若没有连接两个不同黑格子的边,那么回路上一个黑格子后必然接一个白格子。那么回路的黑格子数目一定小于等于白格子数目。但是棋盘上的黑格子数目比白格子多一。矛盾。

若存在一个连接两个不同黑格子的边,那么一定存在一条合法的方案。

两个思路:

1)按照起点终点位置分类讨论构造

2)归纳证明

若有一维大于5,一定可以将其减2

归纳到n,m<=5的情况,此时可以自行验证

 

根据题解说棋盘黑白染色 ,当且仅当新增的边连接了两个不同的黑色格子。发现黑色格子都有个规律,纵坐标加横坐标为偶数,在避免是同一点。如果能找到答案为n*m,如果不能答案为n*m+1

#include<bits/stdc++.h>
using namespace std;
const double PI=acos(-1.0);
typedef long long ll;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define clr(x) memset(x,0,sizeof(x))
const int INF=0x3f3f3f3f;
int main(){
	//本地测试
	#ifdef ONLINE_JUDGE
	#else
    freopen("C://Users//yan//Desktop//in.txt","r",stdin);
	#endif
	ios::sync_with_stdio(false);//取消同步
	std::cin.tie(0);//解除cin与cout的绑定,进一步加快执行效率。
	int t;
	cin>>t;
	while(t--){
		int n,m,k;
		int len=1;
		cin>>n>>m>>k;
		if(n%2==0||m%2==0){
			len=0;
		}		
		rep(i,0,k){
			int a,b,c,d;
			cin>>a>>b>>c>>d;
			if((a+b)%2==0&&(d+c)%2==0&&(a!=c||b!=d))
			len=0;
		}
		cout<<n*m+len<<endl;
	} 
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值