题目描述
给出一张n行m列的网格图(n条水平线,m条竖直线),要求你给图中的每一条边定向,并且规定每条边允许的通过次数(需要通过至少一次),使得最后得到的图存在一条欧拉回路(一条通过所有的边的回路,且每条边实际通过次数允许通过次数),我们要使每条边的通过次数之和最小。
我们本来需要你给出具体的构造方案。如果存在多种方案,输出任意一组。
但是现在我们只需要你输出最值即可。
输入
一行两个正整数n,m。
输出
一行一个整数表示答案。
样例输入
3 3
样例输出
16
提示
一种可行的方案:
思路
建立一个无向图欧拉回路的要求是每个点的度为偶数,所以要把每一个点的度变为偶数,对于本题只有四个边除四个角外的其他点是度为奇数,所以要分n和m为奇数偶数的情况,如果说n和m都是偶数的话,那么要加的边为((n-2)/2+(m-2)/2) * 2,如果说n和m都是奇数的话,就是((n-3)/2+(m-3)/2) * 2+4,如果说存在一个奇数,那么就是(n-3)/2*2+(m-4)/2+(m-2)/2+4,最后特判一下n<=2或者m<=2的情况,n == 2的时候是m-2,m == 2的时候是n-2,然后再把上面的值加上构成一个正常的所需要的边数即 n * (m-1)+m * (n-1)
代码实现
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1005;
const int M=1e6+5;
const ll INF=1e16;
const ull sed=31;
const ll mod=1e9+7;
const double eps=1e-8;
typedef pair<int,int>P;
typedef pair<double,double>Pd;
int n,m;
int main()
{
scanf("%d%d",&n,&m);
int sum=n*(m-1)+m*(n-1);
if(n>2 && m>2)
{
if(!(n&1) && !(m&1)) sum+=n+m-4;
else sum+=n+m-2;
}
else if(n<=2) sum+=m-2;
else if(m<=2) sum+=n-2;
printf("%d\n",sum);
return 0;
}