1 条题解

  • 0
    @ 2025-4-9 20:58:43

    题解

    只看可以走多次的边,将这些边组成的连通块缩为一点,问题转化为无向图欧拉回路问题。 当奇数度点为 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
    上传者