Problem - D - Codeforces
思路:思路想到了,但是不知道用什么方法写。。首先我们先看只有一个树的情况,那么如果我们所有的边是一个颜色,那么答案是1+n,如果我们将其中的一条边变色,那么产生的答案是2+n-1,答案是不变的,如果有n条边,同样的方式我们如果所有的边为一个颜色,那么产生答案是1+n,但是n条边的树是存在环的,我们可以将环上的一条边变为另一个颜色那么答案就会变成1+n-1,所以我们通过总结发现,只要同一种颜色没有环,最终的答案就是最小的。那么现在问题就变成了构造两个无环图,我们可以先构造一颗树,那么最多会剩下3条边,如果剩下的三条边能够构成环,那么我们任意的选择一条边,加到树上,然后选择这条边的某个顶点,然后把这个顶点在树种的所有连边全都删除,除了新加的这条边,这样是一定不会有环的,因为首先树上是肯定没有环的,可能剩下的边存在环,因为新砍下来边是从树上看下来的,那么它们之间肯定是不能够形成环的,并且这写边与剩下的两个一定也不能够构成,因为没有重边的存在,要构成环那么只能是之前新加的那条边,所以肯定也不可能
// Problem: D. Edge Split
// Contest: Codeforces - Codeforces Round 819 (Div. 1 + Div. 2) and Grimoire of Code Annual Contest 2022
// URL: https://codeforces.com/contest/1726/problem/D
// Memory Limit: 256 MB
// Time Limit: 2000 ms
#include
#include
#include
#define fi first
#define se second
#define i128 __int128
using namespace std;
typedef long long ll;
typedef double db;
typedef pair PII;
const double eps=1e-7;
const int N=5e5+7 ,M=5e5+7, INF=0x3f3f3f3f,mod=1e9+7,mod1=998244353;
const long long int llINF=0x3f3f3f3f3f3f3f3f;
inline ll read() {ll x=0,f=1;char c=getchar();while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=(ll)x*10+c-'0';c=getchar();} return x*f;}
inline void write(ll x) {if(x < 0) {putchar('-'); x = -x;}if(x >= 10) write(x / 10);putchar(x % 10 + '0');}
inline void write(ll x,char ch) {write(x);putchar(ch);}
void stin() {freopen("in_put.txt","r",stdin);freopen("my_out_put.txt","w",stdout);}
bool cmp0(int a,int b) {return a>b;}
template T gcd(T a,T b) {return b==0?a:gcd(b,a%b);}
template T lcm(T a,T b) {return a*b/gcd(a,b);}
void hack() {printf("\n----------------------------------\n");}
int T,hackT;
int n,m,k;
int ans[N];
PII edge[N];
int f[N];
int h[N],e[M],ne[M],idx;
bool st[N];
void add(int a,int b) {
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int find(int x) {
if(x!=f[x]) f[x]=find(f[x]);
return f[x];
}
int dfs(int u,int fa,bool &flag) {
if(st[u]) {
flag=true;
return 0;
}
st[u]=true;
int res=1;
for(int i=h[u];i!=-1;i=ne[i]) {
int j=e[i];
if(j==fa) continue;
res+=dfs(j,u,flag);
}
return res;
}
bool check(vector &vis) {
for(int i=0;i<=n;i++) h[i]=-1,st[i]=false;
idx=0;
for(int i=0;i vis;
for(int i=1;i<=m;i++) {
int a=read(),b=read();
edge[i]={a,b};
int fa=find(a),fb=find(b);
if(fa!=fb) {
f[fa]=fb;
ans[i]=1;
}else vis.push_back({a,b});
}
if(vis.size()==3) {
if(check(vis)) {
int id=vis[0].fi;
for(int i=1;i<=m;i++) {
if(!ans[i]) continue;
if(edge[i].fi==id||edge[i].se==id) ans[i]=0;
}
for(int i=1;i<=m;i++) {
if(edge[i].fi==vis[0].fi&&edge[i].se==vis[0].se) ans[i]=1;
}
}
}
for(int i=1;i<=m;i++) printf("%d",ans[i]);
printf("\n");
}
int main() {
// init();
// stin();
// ios::sync_with_stdio(false);
scanf("%d",&T);
// T=1;
while(T--) hackT++,solve();
return 0;
}