1 条题解
-
0
题解
只看可以走多次的边,将这些边组成的连通块缩为一点,问题转化为无向图欧拉回路问题。 当奇数度点为 0 个或 2 个的时候为 YES,否则为 NO。 我们只需要关注连通块的度数的奇偶性,可以使用并查集实现缩点。
#include<bits/stdc++.h> #define int long long using namespace std; using PII=std::pair<int,int>; using i64=long long; struct DSU{ std::vector<int> f,sz,deg; DSU(){} DSU(int n){init(n);} void init(int n){ f.resize(n); std::iota(f.begin(),f.end(),0); sz.assign(n,1); } int find(int x){ while(x!=f[x]){ x=f[x]=f[f[x]]; } return x; } bool same(int x,int y){ return find(x)==find(y); } bool merge(int x,int y){ x=find(x),y=find(y); if(x==y)return false; sz[x]+=sz[y]; f[y]=x; return true; } int size(int x){ return sz[find(x)]; } }; void solve(){ int n,m;std::cin>>n>>m; DSU g(n); std::vector<int> deg(n,0),u(m),v(m),tag(m,0); for(int i=0;i<m;i++){ int x,y;std::cin>>x>>y; x--;y--; u[i]=x;v[i]=y; } int k;std::cin>>k; for(int i=0;i<k;i++){ int x;std::cin>>x;x--; tag[x]=true; } for(int i=0;i<m;i++){ if(tag[i])continue; g.merge(u[i],v[i]); } for(int i=0;i<m;i++){ deg[g.find(u[i])]++; deg[g.find(v[i])]++; } int cnt=0; for(int i=0;i<n;i++){ if(g.f[i]!=i)continue; cnt+=deg[i]%2; } std::cout<<(cnt<=2?"Yes\n":"No\n"); } signed main(){ std::cin.tie(nullptr); std::ios::sync_with_stdio(false); std::cout<<std::fixed<<std::setprecision(10); int T=1; //std::cin>>T; while(T--)solve(); return 0; }
- 1
信息
- ID
- 354
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- (无)
- 递交数
- 30
- 已通过
- 7
- 上传者