codeforces 962F Simple Cycles Edges

匿名 (未验证) 提交于 2019-12-03 00:25:02

http://www.elijahqi.win/archives/3603
题意翻译
定义无向图中简单环为某几条边构成的最小环(即该环中不再包含更小的环),现给出n点m条边(n,m<=100000),求恰好被包含在一个(多了少了都不行)简单环中的边,第一行输出这些边个数,第二行根据输入顺序输出这些边编号.数据保证无重边自环,但不一定保证连通.

感谢 @cy1366371760 提供的翻译。

以前一直写点入栈的点双 这次yy一下边入栈 wa不停..

考虑把所有点双搞出来 然后判断每个点双是不是简单环如果是简单环统计答案即可

如果这个点双不是简单环 那么所有的边一定都包含在两个环

直接判断点数是否和边数相同即可

边入栈的时候需要特判时间戳 来判断该边i是否需要入栈

#include<cstdio> #include<cctype> #include<vector> #include<algorithm> using namespace std; inline char gc(){     static char now[1<<16],*S,*T;     if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if(T==S) return EOF;}     return *S++; } inline int read(){     int x=0,f=1;char ch=gc();     while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}     while(isdigit(ch)) x=x*10+ch-'0',ch=gc();     return x*f; } const int N=1e5+10; struct node{     int y,next,id; }data[N<<1]; struct node1{     int x,y,id; }q[N]; int top,n,m,num,ans[N],h[N],dfn[N],low[N],size[N],s,b[N];vector<int> eg[N]; inline void tarjan(int x,int fa){     dfn[x]=low[x]=++num;     for (int i=h[x];i;i=data[i].next){         int y=data[i].y;if (y==fa) continue;         if (dfn[y]&&(dfn[y]<dfn[x]))q[++top]=(node1){x,y,data[i].id};         if (!dfn[y]){             q[++top]=(node1){x,y,data[i].id};             tarjan(y,x);low[x]=min(low[x],low[y]);             if (low[y]>=dfn[x]){                 ++s;node1 now;                 while(1){                     now=q[top--];eg[s].push_back(now.id);                     if (b[now.x]!=s) ++size[s],b[now.x]=s;                     if (b[now.y]!=s) ++size[s],b[now.y]=s;                      if (now.x==x&&now.y==y) break;                 }             }         }else low[x]=min(low[x],dfn[y]);     } } int main(){     freopen("cf962f.in","r",stdin);     n=read();m=read();     for (int i=1;i<=m;++i){         int x=read(),y=read();         data[++num].y=y;data[num].next=h[x];h[x]=num;data[num].id=i;         data[++num].y=x;data[num].next=h[y];h[y]=num;data[num].id=i;     }num=0;     for (int i=1;i<=n;++i) if (!dfn[i]) tarjan(i,i);top=0;     for (int i=1;i<=s;++i)         if(eg[i].size()==size[i])             for (int j=0;j<eg[i].size();++j) ans[++top]=eg[i][j];     sort(ans+1,ans+top+1);printf("%d\n",top);     for (int i=1;i<=top;++i) printf("%d ",ans[i]);     return 0; }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!