One of Hu botao's questions in this paper is classical modeling. Since every bit in the binary system is different or does not affect each other, we convert the problem model and process it by bit.
That is, we know that the number of vertices is 0/1 (and some can be changed as needed). With some edges, the edge weight is defined as the exclusive or of the vertex labels at both ends, and the Edge Weight and minimum labeling scheme are required.
We think that the smallest cut is the edge weight with the smallest capacity from the source to the sink.
Graph creation:
1 is connected to the Source Vertex. If the size is INF and the value is 0, it is connected to the sink vertex. If the size is INF, these edges cannot be cut (these vertex labels are already clear)
Edge connecting the source image, with a capacity of 1. (If this edge is cut off, one of the two ends is 0, one is 1, and the cut is 1)
After running the maximum stream, find the s set in the DFS of the residual network, that is, these points belong to 1.
#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<set>#include<map>#include<queue>#include<vector>#include<string>#define eps 1e-12#define INF 0x7fffffff#define maxn 22222using namespace std;int n,m,k;int en;int st,ed;int dis[maxn];int que[9999999];int cur[maxn];struct edge{ int to,c,next;};edge e[9999999];int head[maxn];void add(int a,int b,int c){ e[en].to=b; e[en].c=c; e[en].next=head[a]; head[a]=en++; e[en].to=a; e[en].c=0; e[en].next=head[b]; head[b]=en++;}int bfs(){ memset(dis,-1,sizeof(dis)); dis[st]=0; int front=0,rear=0; que[rear++]=st; while(front<rear) { int j=que[front++]; for(int k=head[j];k!=-1;k=e[k].next) { int i=e[k].to; if(dis[i]==-1&&e[k].c) { dis[i] = dis[j]+ 1 ; que[rear++]=i; if(i==ed) return true; } } } return false;}int dfs(int x,int mx){ if(x==ed || mx==0) return mx; int f,flow=0; for(int& i=cur[x];i!=-1;i=e[i].next) { if(dis[x]+1==dis[e[i].to] && (f=dfs(e[i].to,min(mx,e[i].c)))) { e[i].c-=f; e[i^1].c+=f; flow+=f; mx-=f; if(!mx)break; } } return flow;}void init(){ en=0; st=0; ed=n+1; memset(head,-1,sizeof(head));}int dinic(){ int tmp=0; int maxflow=0; while(bfs()) { for(int i=st;i<=ed;i++) cur[i]=head[i]; while(tmp=dfs(st,INF)) maxflow+=tmp; } return maxflow;}bool mp[505][505],vis[505];int mark[505];int id[505];void p(int a,int b,int w){ printf("%d->%d = %d\n",a,b,w);}void build(int move){ for(int i=1;i<=k;i++) { if((1<<move)&mark[id[i]]) { add(st,id[i],INF); } else { add(id[i],ed,INF); } } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(mp[i][j]) { add(i,j,1); } } }}void get(int now,int move){ vis[now]=1; mark[now]|=(1<<move); for(int i=head[now];~i;i=e[i].next) if(e[i].c&&!vis[e[i].to]) get(e[i].to,move);}int main(){ int cas,a,b; scanf("%d",&cas); while(cas--) { scanf("%d%d",&n,&m); memset(mark,0,sizeof(mark)); memset(mp,0,sizeof(mp)); for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); mp[a][b]=1; mp[b][a]=1; } scanf("%d",&k); for(int i=1;i<=k;i++) { scanf("%d%d",&a,&b); mark[a]=b; id[i]=a; } for(int i=0;i<=31;i++) { init(); build(i); dinic(); memset(vis,0,sizeof(vis)); get(st,i); } for(int i=1;i<=n;i++) { printf("%d\n",mark[i]); } } return 0;}