Description
Defines the value of an edge in an image without a direction: An XOR value for the value of two points connected by this edge.
Defines the value of an none-graph: The and of the values of all sides of this non-graph.
Give you an no-show graph with n nodes m edges. The value of some of these points is given, and the value of the remaining points is determined by you (but the requirements are non-negative), so that the value of this graph is minimized. Under the premise of the least value of the non-direction graph, the value and the smallest of the values in the graph are made. Input
The first line, two number n,m, represents the number of points and sides of a graph.
Next n rows, one number per line, and the value of each point by number (if negative, the value of this point is determined by you, the value of the absolute size does not exceed 10^9).
The next M-line, two numbers per line, a, a, represents an edge between two points numbered A and B. (Guaranteed no heavy side with self-loop.) ) Output
The first row, a number, represents the value of the non-graph. The
second row, a number, represents the and of the values that are somewhat in the non-graph.
Sample Input
3 2
2
-1
0
1 2
2 3
Sample Output
2
2
HINT
Data conventions
n<=500,m<=2000 Sample Explanation
The value of 2 nodes is set to 0.
Solving
Binary questions we can not difficult to think of each to separate discussion, if not to consider the second question, two points to choose a different weight, it becomes a very bare minimum cut model, plus the second question, we just put Benquan by a very large value on the line, the last ans/inf for the first answer, Ans%inf The answer to the second question
#include <cstdio> #include <cstdlib> #include <ctime> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <iomanip> using namespace
Std
#define INF 0x3f3f3f3f int val[501];
int l[3001];
int r[3001]; struct Bian {int l,r,f;}
A[20000];
int fir[510];
int nex[20000];
int d[510];
int s=0,t=509;
int tot=1;
void _add_edge (int l,int r,int f) {a[++tot].l=l;
A[tot].r=r;
A[tot].f=f;
NEX[TOT]=FIR[L];
Fir[l]=tot;
} void Add_edge (int l,int r,int f) {_add_edge (l,r,f);
_add_edge (r,l,0);
} bool BFs () {static int dui[510];
int s=1,t=1;
Memset (d,-1,sizeof (d));
Dui[t++]=s;
d[s]=0;
while (s<t) {int u=dui[s++];
for (int o=fir[u];o;o=nex[o]) {if (!A[O].F) continue;
if (d[a[o].r]!=-1) continue;
d[a[o].r]=d[u]+1;
DUI[T++]=A[O].R;
if (a[o].r==t) return true;
} } return false;
} int dinic (int u,int flow) {if (u==t) return flow;
int left=flow;
for (int o=fir[u];o && Left;o=nex[o]) {if (!a[o].f | | d[a[o].r]!=d[u]+1) continue;
int Temp=dinic (A[o].r,min (a[o].f,left));
A[o].f-=temp;
A[o^1].f+=temp;
Left-=temp;
if (!temp) d[a[o].r]=-1;
} return flow-left;
} int main () {int n,m;
scanf ("%d%d", &n,&m);
for (int i=1;i<=n;i++) scanf ("%d", &val[i]);
for (int i=1;i<=m;i++) scanf ("%d%d", &l[i],&r[i]);
Long Long ans1=0,ans2=0;
for (int i=0;i<=30;i++) {tot=1;
memset (fir,0,sizeof (FIR));
for (int j=1;j<=n;j++) {if (val[j]<0) Add_edge (s,j,1);
else if (val[j]& (1<<i)) {Add_edge (j,t,inf);
Add_edge (s,j,1);
} else Add_edge (S,j,inf);
} for (int j=1;j<=m;j++) { Add_edge (l[j],r[j],10000);
Add_edge (r[j],l[j],10000);
} int ans=0;
while (BFS ())) ans+=dinic (S,inf);
ans1+=1ll* (ans/10000) * (1<<i);
ans2+=1ll* (ans%10000) * (1<<i);
} cout<<ans1<<endl<<ans2<<endl;
return 0; }