题目大意
定义了一个鱼图,求是否存在并输出环和两点的边。
题意分析
直接暴力,但是需要加一点点小优化,具体如下:
- 环的检测:我们首先需要在图中找到一个环,如果遇到了一个已经访问过的节点,并且该节点不是当前路径的父节点,就形成了一个环。
- 检查环的特殊节点:鱼图的要求是环中的某个节点,除了参与环的连接,还必须有两条指向环外的边。
- 遍历所有可能的环:环的起始节点可能是任意的,因此我们需要遍历所有节点,尝试从每个节点出发找到一个环,并判断该环是否符合鱼图的要求。同时由于是环,所以这个点必须有被四个点连接。
具体可参考代码及注释理解。
CODE
#include<bits/stdc++.h>
#define wk(x) write(x),putchar(' ')
#define wh(x) write(x),putchar('\n')
#define ll long long
#define ull unsigned long long
#define ri register int
#define INF 2147483647
#define mod 998244353
#define N 50005
#define NO printf("No\n")
#define YES printf("Yes\n")using namespace std;
int n,m,k,jk,ans,sum,num,cnt,tot;
int head[N],dis[N],vis[N],wis[N],f[N];void read(int &x)
{x=0;int ff=1;char ty;ty=getchar();while(!(ty>='0'&&ty<='9')){if(ty=='-') ff=-1;ty=getchar();}while(ty>='0'&&ty<='9')x=(x<<3)+(x<<1)+ty-'0',ty=getchar();x*=ff;return;
}void write(int x){if(x==0){putchar('0');return;}if(x<0){x=-x;putchar('-');}char asd[201];int ip=0;while(x) asd[++ip]=x%10+'0',x/=10;for(int i=ip;i>=1;i--) putchar(asd[i]);return;
}struct lenovo{int to,nxt,val;
}v[N*2];void add(int x,int y)
{v[++cnt].to=y;v[cnt].nxt=head[x];head[x]=cnt;
}void dfs(int x,int y,int z){if(tot) return;f[++num]=x;vis[x]=1;//加入堆中。for(int i=head[x];i&&!tot;i=v[i].nxt){int u=v[i].to;if(u==y) continue;if(u==z&&y!=z){//到达原点。memset(dis,0,sizeof dis);int pop=0;//初始化。for(int j=1;j<=num;j++) dis[f[j]]=1;//标记堆中的元素。for(int j=head[z];j&&pop<2;j=v[j].nxt)if(!dis[v[j].to]) pop++;//取另外两点。if(pop<2) continue;//不符合条件就退出。YES;wh(num+2);//输出答案。for(int j=num;j>1;j--) wk(f[j]),wh(f[j-1]);wk(z),wh(x);pop=0;for(int j=head[z];j&&pop<2;j=v[j].nxt)if(!dis[v[j].to]) wk(z),wh(v[j].to),pop++;tot=1;return;}if(!vis[u]) dfs(u,x,z);//继续遍历。}num--;//弹出堆顶。
}signed main()
{read(jk);while(jk--){read(n),read(m);int x,y;cnt=0;memset(head,0,sizeof head);//记得初始化。memset(wis,0,sizeof wis);for(int i=1;i<=m;i++){read(x),read(y);add(x,y),add(y,x);wis[x]++,wis[y]++;//将出度和入度加一。}tot=0;for(int i=1;i<=n&&!tot;i++){if(wis[i]<4) continue;//一定不可能是。memset(vis,0,sizeof vis);dfs(i,0,i);num=0;//暴力。}if(!tot) NO;//无解的情况。}return 0;
}