【題解】[牛客網NOIP賽前集訓營-提高組(第三場)]B.公平競賽 bfs
阿新 • • 發佈:2018-11-01
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; inline int read() { int s=0,f=0;char ch=getchar(); while(ch<'0'||ch>'9')f|=ch=='-',ch=getchar(); while(ch>='0'&&ch<='9')s=(s<<1)+(s<<3)+(ch^48),ch=getchar(); if(f)s=-s;return s; } const int N=5e3+10; const int M=1e6+10; const int INF=0x3f3f3f3f; int op,n,m,tot,hd[N<<1],vis[N<<1],len[N<<1],ans[N<<1],minn=INF,pre[N<<1]; struct Edge{ int v,nx; }e[M<<1]; inline void add(int u,int v) { e[++tot].v=v; e[tot].nx=hd[u]; hd[u]=tot; } inline void bfs(int s) { memset(vis,0,sizeof(vis));memset(len,0,sizeof(len));memset(pre,0,sizeof(pre)); queue<int>q;while(q.size())q.pop();q.push(s);vis[s]=1; while(q.size()) { int u=q.front();q.pop(); if(2*len[u]+1>=minn)return; for(int i=hd[u];i;i=e[i].nx) { int v=e[i].v; if(v==pre[u])continue; if(!vis[v]) { vis[v]=1;q.push(v);pre[v]=u;len[v]=len[u]+1; } else { if(len[u]+len[v]+1<minn) { minn=len[u]+len[v]+1; int tp=0; for(int j=u;j;j=pre[j])ans[++tp]=j; reverse(ans+1,ans+tp+1); for(int j=v;j;j=pre[j])ans[++tp]=j; } return; } } } } int main() { //freopen("in.txt","r",stdin); op=read(); while(1) { n=read();if(!n)break;m=read(); memset(hd,0,sizeof(hd));tot=0;minn=INF; for(int i=1,a,b;i<=m;i++) a=read(),b=read(),add(a,b+n),add(b+n,a); for(int i=1;i<=n;i++)bfs(i); if(minn==INF)puts("-1"); else { printf("%d\n",minn); for(int i=1;i<=minn;i++) printf("%d ",ans[i]>n?ans[i]-n:ans[i]); puts(""); } } return 0; }
總結
拆點後在二分圖中bfs找最小環