思路:思路想到了,但是不知道用什么方法写。。首先我们先看只有一个树的情况,那么如果我们所有的边是一个颜色,那么答案是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<int,int> 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<typename T> T gcd(T a,T b) {return b==0?a:gcd(b,a%b);}
- template<typename T> 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
size();i++) { - int a=vis[i].fi,b=vis[i].se;
- add(a,b),add(b,a);
- }
-
- bool flag=false;
- if(dfs(vis[0].fi,-1,flag)==3&&flag) return true;
- else return false;
- }
-
- void solve() {
- n=read(),m=read();
-
- for(int i=1;i<=n;i++) f[i]=i;
- for(int i=1;i<=m;i++) ans[i]=0;
-
- vector
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;
- }