Codeforces Round #819 D

D. Edge Split

n+2条边 并且连通图 就证明最多多3条边
我们可以想到的是要是连成了环的话 不如拆一条边给其他颜色 所以我们一定要无环
我们先跑一遍最小生成树确定成红色 要是m=n+2 才有可能多三条构成环
那我们考虑将他其中一条边变红 这样红色必然会出现环
我们考虑将刚刚变红的一个端点的另一条红色变蓝试试 但其实是不合规的
因为该点出边可能有4 这样就算减去2 还是可能构成环 我们试着直接把他所有出边(除了刚刚变红的)全变蓝色 这样就只有一条出边
我们的环就不复存在了

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define YES cout<<"Yes"<<endl;
#define NO cout<<"No"<<endl;
#define _ 0
#define pi acos(-1)
#define INF 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int p[N];
int find(int x){
    if(p[x]!=x)p[x]=find(p[x]);
    return p[x];
}
void merge(int x, int y){
    p[find(x)] = find(y);
}
struct node{
    int u,v,id;
};
void solve() {
    int n,m;cin>>n>>m;
    for(int i=0;i<=n;i++)p[i]=i;
    vector<int>g[n+1];
    vector<node>e(m+1);
    for(int i=1;i<=m;i++){
        cin>>e[i].u>>e[i].v;e[i].id=i;
        auto [u,v,id]=e[i];
        g[u].push_back(v);
        g[v].push_back(u);
    }
    set<int>s;
    vector<int>ans(m+1);
    vector<node>B,R;
    for(int i=1;i<=m;i++){
        auto [u,v,id]=e[i];
        if(find(u)!=find(v)){
            merge(u,v);
            R.push_back(e[i]);
            ans[i]=1;
        }else{
            B.push_back(e[i]);
            s.insert(u),s.insert(v);
        }
    }
    if(s.size()==3&&B.size()==3){
        auto ed=B.back();
        ans[ed.id]=1;
        for(auto r:R){
            if(r.u==ed.u||r.v==ed.u)ans[r.id]=0;
        }
    }
    for(int i=1;i<=m;i++)cout<<ans[i];cout<<endl;
}
signed main(){
    fast
    int T;cin>>T;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}
posted @ 2022-09-19 18:28  ycllz  阅读(29)  评论(0)    收藏  举报