题解P6853
大概是目前唯一一篇带证明的题解吧
趁着没有题解赶紧来一篇
以下
因为
首先,题意里面的"路径"是很丑陋的,我们尝试简化一下题意
我们尝试把每一条路径对应成一个点,两个路径相连则把他们连上一条边
显然最优情况下每个车站都经过三条路径
则:对于每一个车站,他被路径
现在考虑题目的第三条限制:每两个点都有一个点和他们都相连
记三元组
其中
由于对每个不同的
则我们有:
对于一个点
则使得
所以:
又每一个点
由简单的数学运算(或者使用人类的直觉),可以知道:
使得
由
又因为每个
所以
接下来给出一组
把车站分成两组:
组
组
此时至多出现
所以,我们确保了这个程序完美满足要求了
最后,放代码了
#include <bits/stdc++.h>
//#include <windows.h>
//#define int long long
using namespace std;
#define N 4001
vector<int>mp[N];
int a[N],b[N],c[N];
int top=0;
int n;
int main()
{
scanf("%d",&n);
for(int i=2; i<=n; i+=2)//处理组1的车站
{
top++;
a[top]=1;
b[top]=i;
c[top]=i+1;
if(i==n)
{
c[top]=2;
}
}
for(int i=2; i<=n; i+=3)//处理组2的车站
{
top++;
a[top]=i;
b[top]=i+1;
if(i+1>=n+1)
{
b[top]-=n;
}
c[top]=i+2;
if(i+2>=n+1)
{
c[top]-=n;
}
}
for(int i=1; i<=top; i++)//把车站信息存进路径
{
mp[a[i]].push_back(i);
mp[b[i]].push_back(i);
mp[c[i]].push_back(i);
}
printf("%d\n",top);
for(int i=1; i<=n; i++)
{
printf("%d ",mp[i].size());
for(int j=0; j<mp[i].size(); j++)
{
printf("%d ",mp[i][j]);
}
printf("\n");
}
return 0;
}
修正:34行敲成了