挫爆了跑了快4s
做法比较挫,先dfs到终点,即找一个路径,标记下,(割边只可能是路径上的),然后tarjan下即可
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<set> #define MAXN 10003 #define MAXM 200033 using namespace std; int n,m,dfn[MAXN],low[MAXN],head[MAXN],cnt,v[MAXN],ans[MAXN],tot,sum; struct EDGE { int to,nxt,tag,cur,db; }edge[MAXM]; void init() { cnt=tot=sum=0; memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(v,0,sizeof(v)); } void add(int x,int y,int i) { int j; for(j=head[x];j!=-1;j=edge[j].nxt) { if(edge[j].to==y) break; } if(j!=-1) { edge[j].db=1; return; } edge[cnt].to=y; edge[cnt].nxt=head[x]; edge[cnt].tag=0; edge[cnt].cur=i; edge[cnt].db=0; head[x]=cnt++; } void addedge(int x,int y,int i) { add(x,y,i); add(y,x,i); } int dfs(int x) { v[x]=1; if(x==n-1) return 1; for(int j=head[x];j!=-1;j=edge[j].nxt) { int y=edge[j].to; if(v[y]) continue; edge[j].tag=1; edge[j^1].tag=1; v[y]=1; if(dfs(y))return 1; edge[j].tag=0; edge[j^1].tag=0; } return 0; } void tarjan(int x,int fa) { dfn[x]=low[x]=++tot; for(int j=head[x];j!=-1;j=edge[j].nxt) { int y=edge[j].to; if(!dfn[y]) { tarjan(y,x); low[x]=min(low[x],low[y]); if(edge[j].tag&&low[y]>dfn[x]&&!edge[j].db) ans[sum++]=edge[j].cur; } else if(y!=fa) low[x]=min(low[x],dfn[y]); } } int main() { while(2==scanf("%d%d",&n,&m)) { int a,b; init(); for(int i=0;i<m;i++) { scanf("%d%d",&a,&b); addedge(a,b,i); } dfs(0); tarjan(0,-1); sort(ans,ans+sum); printf("%d\n",sum); for(int i=0;i<sum;i++) { if(i==0) printf("%d",ans[i]); else printf(" %d",ans[i]); } puts(""); } return 0; }