一个无向图,每个点有点权,某些点点权确定了,某些点由你来确定,边权为两个点的异或和,要使边权和最小。
这不是一道按位做最小割的大水题么
非常开心地打了,还非常开心地以为有spj,然后非常开心地Wa了
才发现在边权和最小的条件下还要让点权和最小。
这可咋整啊,难不成要费用流。
然后悄悄搜了下题解发现了巧妙的解决方法,把原来建的图中的边权都扩大10000倍,然后在选1的地方边权再悄悄加上1
把它看成10000和1两条边的话,相当于优先考虑大边最小,大边最小的前提下小边最小,即答案。
1 //Achen
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdlib>
6 #include<vector>
7 #include<cstdio>
8 #include<queue>
9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define Formylove return 0
13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
15 const int M=3500*10,N=550;
16 typedef long long LL;
17 typedef double db;
18 using namespace std;
19 int n,m,k,qd[N],val[N],ec[M][2];
20
21 template<typename T>void read(T &x) {
22 char ch=getchar(); x=0; T f=1;
23 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
24 if(ch=='-') f=-1,ch=getchar();
25 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
26 }
27
28 struct edge {
29 int u,v,cap,fl,nx;
30 edge(){}
31 edge(int u,int v,int cap,int fl,int nx):u(u),v(v),cap(cap),fl(fl),nx(nx){}
32 }e[M];
33
34 int ecnt=1,fir[N];
35 void add(int u,int v,int cap) {
36 e[++ecnt]=edge(u,v,cap,0,fir[u]); fir[u]=ecnt;
37 //printf("%d->%d:%d
",u,v,cap);
38 e[++ecnt]=edge(v,u,0,0,fir[v]); fir[v]=ecnt;
39 }
40
41 queue<int>que;
42 int d[N];
43 void bfs(int s,int t) {
44 que.push(t);
45 For(i,1,n) d[i]=n;
46 d[t]=0;
47 while(!que.empty()) {
48 int x=que.front();
49 que.pop();
50 for(int i=fir[x];i;i=e[i].nx) {
51 int y=e[i].v;
52 if(d[y]==n&&e[i].cap==0) {
53 d[y]=d[x]+1;
54 que.push(y);
55 }
56 }
57 }
58 }
59
60 #define inf 1e9
61 int p[N];
62 int calc(int s,int t) {
63 int fl=inf;
64 for(int i=t;i!=s;i=e[p[i]].u)
65 fl=min(fl,e[p[i]].cap-e[p[i]].fl);
66 for(int i=t;i!=s;i=e[p[i]].u)
67 e[p[i]].fl+=fl,e[p[i]^1].fl-=fl;
68 return fl;
69 }
70
71 int c[N],cur[N];
72 int isap(int s,int t) {
73 For(i,0,n) c[i]=0;
74 bfs(s,t);
75 For(i,1,n) cur[i]=fir[i],c[d[i]]++;
76 int rs=0;
77 for(int x=s;d[x]<n;) {
78 if(x==t) {
79 rs+=calc(s,t);
80 x=s;
81 }
82 int ok=0;
83 for(int &i=cur[x];i;i=e[i].nx) if(e[i].cap>e[i].fl&&d[e[i].v]+1==d[x]) {
84 ok=1; p[x=e[i].v]=i; break;
85 }
86 if(!ok) {
87 int D=n; cur[x]=fir[x];
88 for(int i=fir[x];i;i=e[i].nx) if(e[i].cap>e[i].fl)
89 D=min(D,d[e[i].v]+1);
90 if(!(--c[d[x]])) break;
91 c[d[x]=D]++;
92 if(x!=s) x=e[p[x]].u;
93 }
94 }
95 return rs;
96 }
97
98 void init() {
99 ecnt=1;
100 memset(fir,0,sizeof(fir));
101 }
102
103 int vis[N];
104 void dfs(int x) {
105 vis[x]=1;
106 for(int i=fir[x];i;i=e[i].nx) if(!vis[e[i].v]&&e[i].cap>e[i].fl)
107 dfs(e[i].v);
108 }
109
110 int main() {
111 #ifdef ANS
112 freopen(".in","r",stdin);
113 freopen(".out","w",stdout);
114 #endif
115 int T; read(T);
116 while(T--) {
117 read(n); read(m);
118 For(i,1,m) {
119 read(ec[i][0]);
120 read(ec[i][1]);
121 }
122 read(k);
123 For(i,1,n) val[i]=0,qd[i]=0;
124 For(i,1,k) {
125 int x;
126 read(x); qd[x]=1;
127 read(val[x]);
128 }
129 int s=n+1,t=n+2;
130 For(i,0,30) {
131 init();
132 For(j,1,n) {
133 if(qd[j]) {
134 if(val[j]&(1<<i)) {
135 add(s,j,10000);
136 add(j,t,inf);
137 }
138 else {
139 add(s,j,inf);
140 add(j,t,10000);
141 }
142 }
143 else {
144 add(s,j,10001);
145 add(j,t,10000);
146 }
147 }
148 For(j,1,m) {
149 int u=ec[j][0],v=ec[j][1];
150 add(u,v,10000); add(v,u,10000);
151 }
152 n+=2;
153 isap(s,t);
154 n-=2;
155 memset(vis,0,sizeof(vis));
156 dfs(s);
157 For(j,1,n) if(!vis[j]) val[j]|=(1<<i);
158 }
159 For(i,1,n) printf("%d
",val[i]);
160 //printf("%d
",val[n]);
161 /*long long ans=0;
162 for(int i=1;i<=m;i++) {
163 int u=ec[i][0],v=ec[i][1];
164 ans+=(val[u]^val[v]);
165 }
166 printf("%lld
",ans);*/
167 }
168 Formylove;
169 }
170 /*
171 1
172 6 7
173 1 2
174 2 4
175 1 3
176 2 3
177 4 3
178 1 5
179 5 6
180 4
181 1 5
182 3 1
183 4 7
184 6 2
185 */