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);
}
标签:const,int,Codeforces,819,出边,Round,define
From: https://www.cnblogs.com/ycllz/p/16708646.html