传送门

一个无向图,每个点有点权,某些点点权确定了,某些点由你来确定,边权为两个点的异或和,要使边权和最小。

这不是一道按位做最小割的大水题么

非常开心地打了,还非常开心地以为有spj,然后非常开心地Wa了

才发现在边权和最小的条件下还要让点权和最小。

这可咋整啊,难不成要费用流。

然后悄悄搜了下题解发现了巧妙的解决方法,把原来建的图中的边权都扩大10000倍,然后在选1的地方边权再悄悄加上1

把它看成10000和1两条边的话,相当于优先考虑大边最小,大边最小的前提下小边最小,即答案。

 //Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define Formylove return 0
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int M=*,N=;
typedef long long LL;
typedef double db;
using namespace std;
int n,m,k,qd[N],val[N],ec[M][]; template<typename T>void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} struct edge {
int u,v,cap,fl,nx;
edge(){}
edge(int u,int v,int cap,int fl,int nx):u(u),v(v),cap(cap),fl(fl),nx(nx){}
}e[M]; int ecnt=,fir[N];
void add(int u,int v,int cap) {
e[++ecnt]=edge(u,v,cap,,fir[u]); fir[u]=ecnt;
//printf("%d->%d:%d\n",u,v,cap);
e[++ecnt]=edge(v,u,,,fir[v]); fir[v]=ecnt;
} queue<int>que;
int d[N];
void bfs(int s,int t) {
que.push(t);
For(i,,n) d[i]=n;
d[t]=;
while(!que.empty()) {
int x=que.front();
que.pop();
for(int i=fir[x];i;i=e[i].nx) {
int y=e[i].v;
if(d[y]==n&&e[i].cap==) {
d[y]=d[x]+;
que.push(y);
}
}
}
} #define inf 1e9
int p[N];
int calc(int s,int t) {
int fl=inf;
for(int i=t;i!=s;i=e[p[i]].u)
fl=min(fl,e[p[i]].cap-e[p[i]].fl);
for(int i=t;i!=s;i=e[p[i]].u)
e[p[i]].fl+=fl,e[p[i]^].fl-=fl;
return fl;
} int c[N],cur[N];
int isap(int s,int t) {
For(i,,n) c[i]=;
bfs(s,t);
For(i,,n) cur[i]=fir[i],c[d[i]]++;
int rs=;
for(int x=s;d[x]<n;) {
if(x==t) {
rs+=calc(s,t);
x=s;
}
int ok=;
for(int &i=cur[x];i;i=e[i].nx) if(e[i].cap>e[i].fl&&d[e[i].v]+==d[x]) {
ok=; p[x=e[i].v]=i; break;
}
if(!ok) {
int D=n; cur[x]=fir[x];
for(int i=fir[x];i;i=e[i].nx) if(e[i].cap>e[i].fl)
D=min(D,d[e[i].v]+);
if(!(--c[d[x]])) break;
c[d[x]=D]++;
if(x!=s) x=e[p[x]].u;
}
}
return rs;
} void init() {
ecnt=;
memset(fir,,sizeof(fir));
} int vis[N];
void dfs(int x) {
vis[x]=;
for(int i=fir[x];i;i=e[i].nx) if(!vis[e[i].v]&&e[i].cap>e[i].fl)
dfs(e[i].v);
} int main() {
#ifdef ANS
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
int T; read(T);
while(T--) {
read(n); read(m);
For(i,,m) {
read(ec[i][]);
read(ec[i][]);
}
read(k);
For(i,,n) val[i]=,qd[i]=;
For(i,,k) {
int x;
read(x); qd[x]=;
read(val[x]);
}
int s=n+,t=n+;
For(i,,) {
init();
For(j,,n) {
if(qd[j]) {
if(val[j]&(<<i)) {
add(s,j,);
add(j,t,inf);
}
else {
add(s,j,inf);
add(j,t,);
}
}
else {
add(s,j,);
add(j,t,);
}
}
For(j,,m) {
int u=ec[j][],v=ec[j][];
add(u,v,); add(v,u,);
}
n+=;
isap(s,t);
n-=;
memset(vis,,sizeof(vis));
dfs(s);
For(j,,n) if(!vis[j]) val[j]|=(<<i);
}
For(i,,n) printf("%d\n",val[i]);
//printf("%d\n",val[n]);
/*long long ans=0;
for(int i=1;i<=m;i++) {
int u=ec[i][0],v=ec[i][1];
ans+=(val[u]^val[v]);
}
printf("%lld\n",ans);*/
}
Formylove;
}
/*
1
6 7
1 2
2 4
1 3
2 3
4 3
1 5
5 6
4
1 5
3 1
4 7
6 2
*/

Optimal Marks SPOJ - OPTM的更多相关文章

  1. Optimal Marks SPOJ - OPTM (按位枚举-最小割)

    题意:给一张无向图,每个点有其点权,边(i,j)的cost是\(val_i\ XOR \ val_j\).现在只给出K个点的权值,求如何安排其余的点,使总花费最小. 分析:题目保证权值不超过32位整型 ...

  2. Optimal Marks SPOJ - OPTM(最小割)

    传送门 论文<最小割模型在信息学竞赛中的应用>原题 二进制不同位上互不影响,那么就按位跑网络流 每一位上,确定的点值为1的与S连一条容量为INF的有向边.为0的与T连一条容量为INF的有向 ...

  3. 839. Optimal Marks - SPOJ

    You are given an undirected graph G(V, E). Each vertex has a mark which is an integer from the range ...

  4. Optimal Marks SPOJ 839

    这题远超其他题非常靠近最小割的实际意义: 割边<=>付出代价<=>决定让两个点的值不相同,边权增加 最小割<=>点的值与s一个阵营的与s相同,与t一个阵营的与t相同 ...

  5. 图论(网络流):SPOJ OPTM - Optimal Marks

    OPTM - Optimal Marks You are given an undirected graph G(V, E). Each vertex has a mark which is an i ...

  6. SPOJ OPTM - Optimal Marks

    OPTM - Optimal Marks no tags  You are given an undirected graph G(V, E). Each vertex has a mark whic ...

  7. 【bzoj2400】Spoj 839 Optimal Marks 按位最大流

    Spoj 839 Optimal Marks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 908  Solved: 347[Submit][Stat ...

  8. 【BZOJ2400】Spoj 839 Optimal Marks 最小割

    [BZOJ2400]Spoj 839 Optimal Marks Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. ...

  9. SP839 Optimal marks(最小割)

    SP839 Optimal marks(最小割) 给你一个无向图G(V,E). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记.对于边(u,v),我们定义Cost(u,v)= ...

随机推荐

  1. Postman Interceptor和postman更改id仍然无法使用的,从这里下载相同版本的postman和interceptor插件

    1.postman安装: chrome://extensions/打开,把下载好的postman插件拖到里面就可以了. 2.Postman interceptor安装: chrome://extens ...

  2. Java中的LinkedHashSet

  3. Yii2中一些常用的参数

    系统类型: <?= php_uname() ?> 解译引擎: <?= $_SERVER['SERVER_SOFTWARE'] ?>, Zend: <?= Zend_Ver ...

  4. 如何使用android-support-V7包中ActionBar(Eclipse版)

    $*********************************************************************************************$ 博主推荐 ...

  5. Android中的Service 与 Thread 的区别

    很多时候,你可能会问,为什么要用 Service,而不用 Thread 呢,因为用 Thread 是很方便的,比起 Service 也方便多了,下面我详细的来解释一下. 1). Thread:Thre ...

  6. 4-基于DoG的特征检测子(SIFT:稳定性好,实时性差)

    opencv实现 详细原理:https://blog.csdn.net/u010440456/article/details/81483145

  7. CSS适配,方案

    1.尺寸常用单位:   https://www.cnblogs.com/whitewolf/p/css-em-px-percentage.html px.em.rem.% 2.CSS的长度单位适配方案 ...

  8. zip mysql安装启动方式

    首先在官网(https://dev.mysql.com/downloads/mysql/)下载相应的zip包 然后进行解压找到配置文件 my-default.ini 文件打开进行配置 主要配置以下几项 ...

  9. chromedriver安装(谷歌浏览器驱动安装)

    如果程序执行错误,浏览器没有打开,那么应该是没有装 Chrome 浏览器或者 Chrome 驱动没有配置在环境变量里.下载驱动,然后将驱动文件路径配置在环境变量即可. chromedriver下载地址 ...

  10. MySQL 建库建表规范

    1.约束 1.PrimaryKey(PK)主键 特点:唯一 + 非空,一张表中只能有一个主键约束,一般是一个数字列,最好是无意义的. 2.NOT NULL 非空 特点:不能为空,建议在MySQL中,业 ...