题解:P14146 朝花
这篇文章中定义
首先按照构造题的套路,核心修改操作一般是最小的操作,在这题就是取反
其次注意到,取反
接着发现,一个所有结点度数为偶数的图可以这样清空:
首先,找到结点编号最小,且度数不为
很明显,一轮操作对点度数的改变仅有将
现在的目标是把这个图所有点的度数变为偶数。可以使用下面的方法:
首先,把所有度数为奇数的点放到一个数列中,记为
于是做完了。
分析一下代价:
- 一开始变成所有点读书为偶数的图的时候,最多有
\frac{n}{4} 组,每组代价为16 ,总代价为4n ,加上最后6 个点的组,代价为4n+36 。边数每组最多增加6 条,最多增加\frac{3n}{2} 条边,加上最后6 个点的组,边数为\frac{3n}{2}+15 。 - 设变化后边数为
m' ,则显然要进行m' 次操作(每次减少一条边),代价为9m' ,最大为9m+\frac{27n}{2}+135 。
总代价
常数有些大,但是前面
:::success[code]
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
const int N=3e6+10,mod=998244353;
pair<int,int>e[N];
int ce;
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>pq;
int cur;
vector<int>f[N];
int d[N];
bool vis[N];
map<pair<int,int>,int>mp;
void turn(vector<int>vec)
{
sort(vec.begin(),vec.end());
f[++cur]=vec;
for(int i=0;i<vec.size();i++) for(int j=i+1;j<vec.size();j++)
{
if(mp[{vec[i],vec[j]}]) mp.erase({vec[i],vec[j]});
else mp[{vec[i],vec[j]}]=1;
d[vec[i]]++,d[vec[j]]++;
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=m;i++)
{
pair<int,int>p;
cin>>p.fi>>p.se;
if(p.fi>p.se) swap(p.fi,p.se);
e[i]=p;
mp[p]=1;
d[p.fi]++,d[p.se]++;
}
vector<int>vec;
for(int i=1;i<=n;i++) if(d[i]%2!=0) vec.push_back(i);
if(vec.size()==2)
{
int cnt=0;
for(int i=1;i<=n;i++) if(d[i]%2==0)
{
vec.push_back(i);
cnt++;
if(cnt==4) break;
}
turn(vec);
turn({vec[2],vec[3],vec[4],vec[5]});
}
else if(vec.size()%4==0) for(int i=0;i<vec.size();i+=4) turn({vec[i],vec[i+1],vec[i+2],vec[i+3]});
else
{
for(int i=0;i<vec.size()-6;i+=4) turn({vec[i],vec[i+1],vec[i+2],vec[i+3]});
turn({vec[vec.size()-6],vec[vec.size()-5],vec[vec.size()-4],vec[vec.size()-3],vec[vec.size()-2],vec[vec.size()-1]});
}
for(auto v:mp) if(v.se) pq.push(v.fi);
while(pq.size())
{
auto p=pq.top();pq.pop();
auto q=pq.top();pq.pop();
if(p==q) continue;
pq.push({p.se,q.se});
f[++cur]={p.fi,p.se,q.se};
}
cout<<cur<<'\n';
for(int i=1;i<=cur;i++)
{
cout<<f[i].size()<<' ';
for(auto v:f[i]) cout<<v<<' ';
cout<<'\n';
}
return 0;
}
:::