https://codeforces.com/problemset/problem/1103/C
亂搞了一下午,TLE on 30,換一種方式 TLE on 35。。。
然後看了題解,看了一半,自己想,又wa了好久,最後還是把最後給看了。。。。
假設有c個葉子節點,設dep[1]=1,那麼對於這c個葉子節點(dep[i1]+dep[i2]+...dep[ic])>=n,因爲每個點都會被至少一條路徑覆蓋到,然後根節點1可能會被覆蓋到多次。那麼max{dep[i1],dep[i2]...dep[ic]}>=n/c,所以dfs樹的葉子節點個數和深度是有關係的 。
所以以1位根節點建dfs樹,如果深度>=n/k,直接記路徑,不超過n/k,那麼至少就會有k個葉子節點,對於每個葉子節點除了連向父親的邊,至少還有向上的兩條邊,所以會得到3個環,且至少有一個環的長度>3,設葉子節點爲u,這兩條邊向上到的點爲d1,d2,假設(dep[u]-dep[d1]+1)%3==0,(dep[u]-dep[d1]+1)%3==0,這兩個圓就是不行的,但是從這兩個式子我們發現dep[d1]%3==dep[d2]%3,那麼對於d1...d2.u這個環的長度爲(dep[d1]-dep[d2]+2)一定=2。所以這3個環必有一個符合條件。
由於無向圖dfs樹葉子節點互相沒有到達,所以以每個葉子節點爲第一個點就好了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=5e5+10;
int n,m,ans,cas,k,tot,cnt,up;
bool flag;
int a[maxl],du[maxl],dep[maxl],fa[maxl],leaf[maxl];
vector<int> e[maxl];
bool vis[maxl];
vector<int> b[maxl];
inline void dfs(int len,int u)
{
vis[u]=true;a[len]=u;bool son=false;
if(len==up)
{
ans=1;
for(int i=1;i<=len;i++)
b[1].push_back(a[i]);
return;
}
for(int v:e[u])
{
if(vis[v] || v==fa[u])continue;
dep[v]=dep[u]+1;fa[v]=u;son=true;
dfs(len+1,v);
if(ans)
return;
}
if(!son)
leaf[++tot]=u;
a[len]=0;
}
inline void prework()
{
scanf("%d%d%d",&n,&m,&k);
int u,v;up=n/k+(n%k!=0);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
e[u].push_back(v);du[u]++;
e[v].push_back(u);du[v]++;
}
ans=0;dep[1]=1;fa[1]=0;
dfs(1,1);
}
inline void mainwork()
{
if(ans)
return;
ans=2;int d1,d2,u,d;
for(int i=1;i<=k;i++)
{
d1=0;d2=0;u=leaf[i];
for(int v:e[u])
if(v!=fa[u])
{
if(!d1) d1=v;
else{d2=v;break;}
}
if(dep[d1]<dep[d2])
swap(d1,d2);
if(dep[u]-dep[d1]+1>=3 && (dep[u]-dep[d1]+1)%3!=0)
{
d=u;
while(d!=d1)
{
b[i].push_back(d);
d=fa[d];
}
b[i].push_back(d1);
}
else if(dep[u]-dep[d2]+1>=3 && (dep[u]-dep[d2]+1)%3!=0)
{
d=u;
while(d!=d2)
{
b[i].push_back(d);
d=fa[d];
}
b[i].push_back(d2);
}
else
{
b[i].push_back(u);d=d1;
while(d!=d2)
{
b[i].push_back(d);
d=fa[d];
}
b[i].push_back(d2);
}
}
}
inline void print()
{
if(!ans)
puts("-1");
else if(ans==1)
{
puts("PATH");
printf("%d\n",up);
for(int i=0;i<up;i++)
printf("%d%c",b[1][i],(i==up-1)?'\n':' ');
}
else
{
puts("CYCLES");int l;
for(int i=1;i<=k;i++)
{
l=b[i].size();
printf("%d\n",l);
for(int j=0;j<l;j++)
printf("%d%c",b[i][j],(j==l-1)?'\n':' ');
}
}
}
int main()
{
int t=1;
//scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}