1. 程式人生 > >[SP839]Optimal Marks

[SP839]Optimal Marks

code spa 不同的 truct https 題意 ima 雙向 string

luogu

題意

給你一個無向圖\(G(V,E)\)。 每個頂點都有一個int範圍內的整數的標記。 不同的頂點可能有相同的標記。
對於邊\((u,v)\),我們定義\(Cost(u,v)=\rm mark_u\ xor \ mark_v\)
現在我們知道某些節點的標記了。你需要確定其他節點的標記,以使邊的總成本盡可能小。

sol

既然是異或的話那就按位考慮吧。
每個已經確定的點和\(S\)或者是\(T\)\(inf\)邊。兩個相鄰的點之間連雙向為\(1\)的邊。
直接就是最小割了吧。
跑完最小割後\(dep\)值非零的點就是與\(S\)相連的點,由此可以構造出方案。

code

#include<cstdio>
#include<algorithm> #include<cstring> #include<queue> using namespace std; int gi() { int x=0,w=1;char ch=getchar(); while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if (ch=='-') w=0,ch=getchar(); while (ch>='0'&&ch<='9'
) x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return w?x:-x; } const int N = 505; const int inf = 1e9; struct edge{int to,nxt,w;}a[N<<5]; int Case,n,m,uu[N*6],vv[N*6],k,val[N],S,T,head[N],cnt=1,dep[N],cur[N],ans[N]; queue<int>Q; void link(int u,int v,int w) { a[++cnt]=(edge){v,head[u],w}; head[u]=cnt; a[++cnt]=(edge){u,head[v],w}; head[v]=cnt; } bool
bfs() { memset(dep,0,sizeof(dep)); dep[S]=1;Q.push(S); while (!Q.empty()) { int u=Q.front();Q.pop(); for (int e=head[u];e;e=a[e].nxt) if (a[e].w&&!dep[a[e].to]) dep[a[e].to]=dep[u]+1,Q.push(a[e].to); } return dep[T]; } int dfs(int u,int f) { if (u==T) return f; for (int &e=cur[u];e;e=a[e].nxt) if (a[e].w&&dep[a[e].to]==dep[u]+1) { int tmp=dfs(a[e].to,min(a[e].w,f)); if (tmp) {a[e].w-=tmp;a[e^1].w+=tmp;return tmp;} } return 0; } int Dinic() { int res=0; while (bfs()) { for (int i=1;i<=T;++i) cur[i]=head[i]; while (int tmp=dfs(S,inf)) res+=tmp; } return res; } int main() { Case=gi(); while (Case--) { n=gi();m=gi();S=n+1;T=n+2; for (int i=1;i<=n;++i) val[i]=-1,ans[i]=0; for (int i=1;i<=m;++i) uu[i]=gi(),vv[i]=gi(); k=gi(); while (k--) {int u=gi();val[u]=gi();} for (int j=30;~j;--j) { for (int i=1;i<=T;++i) head[i]=0;cnt=1; for (int i=1;i<=n;++i) if (~val[i]) if (val[i]&(1<<j)) link(S,i,inf);else link(i,T,inf); for (int i=1;i<=m;++i) link(uu[i],vv[i],1); Dinic(); for (int i=1;i<=n;++i) if (dep[i]) ans[i]|=1<<j; } for (int i=1;i<=n;++i) printf("%d\n",ans[i]); } return 0; }

[SP839]Optimal Marks