2 条题解
-
1
事先感慨一句:好水!!
思路
题目要求求无向图的环,这可比P9158简单多了,只需遍历一遍,对每个访问的点先入栈(手动维护),遍历完后续的点时出栈消除影响,并在开始访问时查询是否已经入栈,若是,就说明找到环了,把站内的点和边输出即可,否则继续遍历。
细节:
1: 输出时不能全部输出,要从上一次访问该点时输出,出现棒棒糖状
(我自己起的名字)就会出错2: 一定要考虑到图不连通的情况,样例2会教你做人
AC代码
#include<bits/stdc++.h> using namespace std; const int N=5e5+10; vector<pair<int,int> > G[N]; pair<int,int> s[N]; bool v[N],vv[N]; int top; void dfs(int x,int xfa,int in_id) { if(v[x]) { vector<pair<int,int> > ans; int _top=top; while(s[top].first!=x)ans.push_back({s[top].first,s[top-1].second}),top--; ans.push_back({s[top].first,s[_top].second}); printf("%d\n",ans.size()); for(auto i:ans)printf("%d ",i.first);puts(""); for(auto i:ans)printf("%d ",i.second);puts(""); exit(0); } if(vv[x])return ; v[x]=vv[x]=1; for(auto i:G[x])if(i.second!=in_id) { s[++top]={x,i.second}; dfs(i.first,x,i.second); top--; } v[x]=0; } int main() { int n,m;scanf("%d%d",&n,&m); for(int i=1,x,y;i<=m;i++) { scanf("%d%d",&x,&y); G[x].push_back({y,i-1}); G[y].push_back({x,i-1}); } for(int i=1;i<=n;i++)if(!vv[i])dfs(i,-1,-1); puts("-1"); return 0; } -
0
#include<bits/stdc++.h> using namespace std; const int N=1e6+10; #define PII pair<int,int> vector<PII>G[N]; stack<PII>stk;int v[N],instk[N]; void dfs(int x,int f) { if(instk[x]) { int z=-1;deque<PII>q; while(z!=x) { int y=stk.top().second;z=stk.top().first;stk.pop(); q.push_back({y,z}); } cout<<q.size()<<'\n'; for(auto i:q)cout<<i.second-1<<' ';cout<<'\n'; q.push_back(q.front());q.pop_front(); for(auto i:q)cout<<i.first-1<<' ';cout<<'\n'; exit(0); } if(v[x])return;v[x]=1; for(auto i:G[x])if(i.second!=f) { int y=i.first,w=i.second; stk.push({x,w});instk[x]=1; dfs(y,w); stk.pop();instk[x]=0; } } int main() { int n,m;cin>>n>>m; for(int i=1;i<=m;i++) { int x,y;cin>>x>>y;x++,y++; G[x].push_back({y,i}); G[y].push_back({x,i}); } for(int i=1;i<=n;i++)if(!v[i]) { while(!stk.empty())stk.pop(); dfs(i,0); } puts("-1"); return 0; }
- 1
信息
- ID
- 8160
- 时间
- 500ms
- 内存
- 1024MiB
- 难度
- 6
- 标签
- 递交数
- 30
- 已通过
- 11
- 上传者