Optimal Marks SPOJ - OPTM
一个无向图,每个点有点权,某些点点权确定了,某些点由你来确定,边权为两个点的异或和,要使边权和最小。
这不是一道按位做最小割的大水题么
非常开心地打了,还非常开心地以为有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的更多相关文章
- Optimal Marks SPOJ - OPTM (按位枚举-最小割)
题意:给一张无向图,每个点有其点权,边(i,j)的cost是\(val_i\ XOR \ val_j\).现在只给出K个点的权值,求如何安排其余的点,使总花费最小. 分析:题目保证权值不超过32位整型 ...
- Optimal Marks SPOJ - OPTM(最小割)
传送门 论文<最小割模型在信息学竞赛中的应用>原题 二进制不同位上互不影响,那么就按位跑网络流 每一位上,确定的点值为1的与S连一条容量为INF的有向边.为0的与T连一条容量为INF的有向 ...
- 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 ...
- Optimal Marks SPOJ 839
这题远超其他题非常靠近最小割的实际意义: 割边<=>付出代价<=>决定让两个点的值不相同,边权增加 最小割<=>点的值与s一个阵营的与s相同,与t一个阵营的与t相同 ...
- 图论(网络流):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 ...
- SPOJ OPTM - Optimal Marks
OPTM - Optimal Marks no tags You are given an undirected graph G(V, E). Each vertex has a mark whic ...
- 【bzoj2400】Spoj 839 Optimal Marks 按位最大流
Spoj 839 Optimal Marks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 908 Solved: 347[Submit][Stat ...
- 【BZOJ2400】Spoj 839 Optimal Marks 最小割
[BZOJ2400]Spoj 839 Optimal Marks Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. ...
- SP839 Optimal marks(最小割)
SP839 Optimal marks(最小割) 给你一个无向图G(V,E). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记.对于边(u,v),我们定义Cost(u,v)= ...
随机推荐
- Web前端/全栈核心(html5/css3/js/vue/react/angular/es6/node)观看笔记
a标签中的超链接,需要加 http:// 否则会出现页面找不到. iframe中添加a标签,a标签中的target属性可以控制即将打开的页面,在那个位置显示. _blank 在新窗口中打开被 ...
- java 多上传 CommonsMultipartFile[] files
/** * 视频上传 * ddl * @param request * @param response * @param files * @return * @throws Exception */@ ...
- PHP ftp_alloc() 函数
定义和用法 ftp_alloc() 函数为要上传到 FTP 服务器的文件分配空间. 如果成功,该函数返回 TRUE.如果失败,则返回 FALSE. 语法 ftp_alloc(ftp_connectio ...
- Linux特殊权限设置以及使用
Linux文件权限特殊权限(s-s-t) 什么是suid权限 SUID是可执行文件的特殊文件权限,使其他用户能够以文件所有者的有效权限运行文件. 代替执行权限的正常x代替用户的s(指示SUID )特权 ...
- NX二次开发-Block UI C++界面Object Color Picker(对象颜色拾取器)控件的获取(持续补充)
Object Color Picker(对象颜色拾取器)控件的获取 NX9+VS2012 #include <uf.h> #include <uf_obj.h> UF_init ...
- JAVA并发工具类---------------(CountDownLatch和CyclicBarrier)
CountDownLatch是什么 CountDownLatch,英文翻译为倒计时锁存器,是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 闭锁可以延迟线程的进 ...
- JAVA常用集合解析
ArrayList : 底层基于数组实现,在使用add方法添加元素时,首先校验集合容量,将新添加的值放入集合尾部并进行长度加一,进行自动扩容,扩容的操作时将数据中的所有元素复制到新的集合中. 在指定位 ...
- java xmltojson jsontoxml
JSONObject.fromObject需要的有额外的6个包,必不可少,一定要注意: commons-beanutils-1.9.2.jar commons-collections-3.2 ...
- Lilo的实现
书承上文:http://www.cnblogs.com/long123king/p/3549267.html 我们找一份Lilo的源码来看一下 http://freecode.com/projects ...
- Java对图片压缩
背景:图片上传服务器时候的大小限制取消之后,上传图片太大导致前台显示加载缓慢 需求:服务器对接收到的图片进行压缩 方法:1.上传后的文件保存在临时文件夹“/usr/upload/tmp” 2.压 ...