CF720C Homework&&CF600F Edge coloring of bipartite graph
阿新 • • 發佈:2021-11-11
CF720C Homework
構造題,先每行都塗滿直至逼近答案,然後對於剩下幾層暴搜。
然而換了翻譯之後 \(\sum{n*m} \leq 10^5\),而且加上聯通的限制嗎,貌似直接暴搜也能跑過了,只是慢一些。
總結一下:構造題不要想直接構造出答案,先用一部分達到逼近答案的效果,剩下的部分就可以比較容易地準確獲得答案。
CF600F Edge coloring of bipartite graph
根據大膽猜測小心求證,有一個結論:二分圖最小顏色數等於最大度數。
具體操作上,參考匈牙利演算法,對於 \(u,v\) 的連邊,如果 \(mex(u)!=mex(v)\),就先強行讓這條邊染上 \(mex(u)\)
點選檢視程式碼
#include<bits/stdc++.h> using namespace std; #define ll long long const int INF = 0x3f3f3f3f,N = 2021,M = 1e5+10; inline ll read() { ll ret=0;char ch=' ',c=getchar(); while(!(c>='0'&&c<='9')) ch=c,c=getchar(); while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar(); return ch=='-'?-ret:ret; } int a,b,m; int u[M],v[M]; int col[N<<1][N]; int ind[N<<1]; signed main() { a=read(),b=read(),m=read(); for(int i=1;i<=m;i++) { u[i]=read(),v[i]=read()+a; ind[v[i]]++,ind[u[i]]++; } int ans=0; for(int i=1;i<=2000;i++) ans=max(ans,ind[i]); for(int i=1;i<=m;i++) { int x=1,y=1; while(col[u[i]][x]) x++; while(col[v[i]][y]) y++; col[u[i]][x]=v[i],col[v[i]][y]=u[i]; if(x==y) continue; int now=u[i],w=x; while(now) { swap(col[now][x],col[now][y]); now=col[now][w]; w^=(x^y); } } printf("%d\n",ans); for(int i=1;i<=m;i++) for(int j=1;j<=ans;j++) if(col[u[i]][j]==v[i]) printf("%d ",j); return 0; }