CF1198C Matching vs Independent Set(构造题)

一个经验是,这种询问两种有些互斥的情况的构造题,往往都是有解的,CF出过很多类似题,特别是给定了一些奇怪的点数,例如倍数之类的

往往一种情况取反就是另一种情况,以前有些dfs树上找环也是这种题,不过更难一些

话说回来,对于这题,我们可以考虑在加边的时候,对于边两端,如果两个点都没标记过,就标记一下,并把它放入边独立集。做完后没被标记的就是点独立集。

基于的原理是,首先边独立集显然是正确的,其次,假设剩下的有两个未被标记的点直接存在边,那么他一定会在之前的操作中被列入边独立集。因此剩下的都是点独立集

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const int N=5e5+10;
const int M=2e6+10;
const int inf=0x3f3f3f3f;
int st[N];
int ans[N];
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n,m;
        cin>>n>>m;
        int i;
        int cnt=0;
        for(i=1;i<=3*n;i++)
            st[i]=0;
        for(i=1;i<=m;i++){
            int a,b;
            cin>>a>>b;
            if(!st[a]&&!st[b]){
                ans[++cnt]=i;
                st[a]=st[b]=1;
            }
        }
        if(cnt<=n){
            cout<<"IndSet"<<endl;
            int id=0;
            for(i=1;i<=3*n;i++){
                if(!st[i]){
                    cout<<i<<" ";
                    id++;
                }
                if(id==n){
                    break;
                }
            }
        }
        else{
            cout<<"Matching"<<endl;
            for(i=1;i<=n;i++)
                cout<<ans[i]<<" ";
            cout<<endl;
        }
    }
}
View Code
没有人不辛苦,只有人不喊疼
原文地址:https://www.cnblogs.com/ctyakwf/p/13629537.html