题意:n点m条边的有向图,操作:改变某条边(u,v)的方向.
n<=1e5,m<=3e5. 可以操作任意次.问入度等于出度的点最多有多少个,并输出改变边的方案.
先把边看成没有方向的,那么如果一个点的度数为奇数,则它的入度不可能等于出度.
那么在奇数点之间连边不会对任意一个方案造成影响.
n<=1e5,m<=3e5. 可以操作任意次.问入度等于出度的点最多有多少个,并输出改变边的方案.
先把边看成没有方向的,那么如果一个点的度数为奇数,则它的入度不可能等于出度.
那么在奇数点之间连边不会对任意一个方案造成影响.
因为奇数点的个数为偶数个.两两连边后,所有点都为偶数度,跑一遍欧拉路径时,保存边的方向即可.O(E).
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> ii;
const int N=4e5+5;
int n,m,mk[N],deg[N];
vector<ii> edg;
vector<int> g[N],a;
void dfs(int u){
for(auto i:g[u]){
if(mk[i]) continue;
auto e=edg[i];
mk[i]=1;
if(e.second==u) mk[i]=2;
dfs(e.second==u?e.first:e.second);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
for(int i=0;i<m;i++){
int u,v;
cin>>u>>v;
edg.push_back(ii(u,v));
g[u].push_back(i);
g[v].push_back(i);
deg[u]++,deg[v]++;
}
for(int i=1;i<=n;i++) if(deg[i]&1) a.push_back(i);
int tot=m;
for(int i=0;i<a.size();i+=2){
int u=a[i],v=a[i+1];
edg.push_back(ii(u,v));
g[u].push_back(tot);
g[v].push_back(tot);
tot++;
}
for(int i=1;i<=n;i++) dfs(i);
cout<<n-a.size()<<'\n';
for(int i=0;i<m;i++)
{
if(mk[i]==1) mk[i]=0;
if(mk[i]==2) mk[i]=1;
cout<<mk[i];
}
return 0;
}