SPOJ839 OPTM - Optimal Marks
闵神讲网络流应用的例题,来水一水
要写出这道题,需要深入理解两个概念,异或和最小割。
异或具有相对独立性,所以我们把每一位拆开来看,即做大概$32$次最小割。然后累加即可。
然后是最小割把一张图分割成两个集合,简单看就是0集合和1集合。
简单的建图:
原图不变,改成双向边,所有的流量限制为1。然后所有S点向点权为1的连边,点权为0的向T连边,容量都是正无穷。
为什么这样建?首先看,最小割把一张图分成两个点集。而因为我们的流量限制可以让最小割只割真实存在的边,而割的也只有可能是跨越0集合和1集合的边。所以最后的最小割就是答案。
//SPOJ839 //by Cydiater //2017.1.15 #include <iostream> #include <cmath> #include <cstring> #include <cstdio> #include <cstdlib> #include <iomanip> #include <queue> #include <map> #include <algorithm> #include <cstring> #include <string> #include <bitset> #include <set> #include <vector> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) #define cmax(a,b) a=max(a,b) #define cmin(a,b) a=min(a,b) #define Auto(i,node) for(int i=LINK[node];i;i=e[i].next) #define vci vector<int> const int MAXN=1e4+5; const int oo=0x3f3f3f3f; inline int read(){ char ch=getchar();int x=0,f=1; while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int LINK[MAXN],len=0,N,M,Val[MAXN],TT,Q,tag[MAXN],S,T,ans=0,q[MAXN],head,tail,level[MAXN]; bool used[MAXN],vis[MAXN]; vci E[MAXN]; struct edge{ int x,y,next,flow,reverse; }e[MAXN<<1]; namespace solution{ void Clear(){ len=0; memset(LINK,0,sizeof(LINK)); } inline void insert(int x,int y,int flow,int delta){ e[++len].next=LINK[x];LINK[x]=len;e[len].y=y; e[len].flow=flow;e[len].reverse=len+delta; } void Prepare(){ Clear(); N=read();M=read(); S=N+1;T=N+2; up(i,1,N)E[i].clear(); up(i,1,M){ int x=read(),y=read(); E[x].push_back(y); E[y].push_back(x); } Q=read(); memset(Val,0,sizeof(Val)); memset(used,0,sizeof(used)); while(Q--){ int node=read(),val=read(); Val[node]=val;used[node]=1; } } void Build(){ Clear(); up(i,1,N){ int siz=E[i].size(); up(j,0,siz-1){ insert(i,E[i][j],1,1); insert(E[i][j],i,0,-1); } } up(i,1,N){ if(tag[i]==1){ insert(S,i,oo,1); insert(i,S,0,-1); }else if(tag[i]==0){ insert(i,T,oo,1); insert(T,i,0,-1); } } } bool makelevel(){ memset(level,-1,sizeof(level)); head=1;tail=0;level[S]=0;q[++tail]=S; for(;head<=tail;head++){ int node=q[head]; Auto(i,node)if(e[i].flow>0&&level[e[i].y]==-1){ level[e[i].y]=level[node]+1; q[++tail]=e[i].y; } } return level[T]!=-1; } int addflow(int node,int flow){ if(node==T) return flow; int maxflow=0,d=0; Auto(i,node)if(level[e[i].y]==level[node]+1&&e[i].flow>0){ if(d=addflow(e[i].y,min(e[i].flow,flow-maxflow))){ maxflow+=d; e[i].flow-=d; e[e[i].reverse].flow+=d; } } if(maxflow==0)level[node]=-1; return maxflow; } void Dinic(int dig){ int d; while(makelevel()) while(d=addflow(S,oo)) ans+=(d<<dig); } void DFS(int node){ vis[node]=1;tag[node]=1; Auto(i,node)if(e[i].flow>0&&!vis[e[i].y]) DFS(e[i].y); } void Solve(){ up(dig,0,31){ up(i,1,N){ if(used[i]) tag[i]=((Val[i]&(1<<dig))>>dig); else tag[i]=-1; } Build(); Dinic(dig); up(i,1,N)tag[i]=0; memset(vis,0,sizeof(vis)); DFS(S); up(i,1,N)if(!used[i])Val[i]|=(tag[i]<<dig); } up(i,1,N)printf("%d\n",Val[i]); } } int main(){ //freopen("input.in","r",stdin); using namespace solution; TT=read(); while(TT--){ Prepare(); Solve(); } return 0; }
SPOJ839 OPTM - Optimal Marks的更多相关文章
- 图论(网络流):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 ...
- 【SPOJ839】Optimal Marks 网络流
You are given an undirected graph G(V, E). Each vertex has a mark which is an integer from the range ...
- SPOJ 839 OPTM - Optimal Marks (最小割)(权值扩大,灵活应用除和取模)
http://www.spoj.com/problems/OPTM/ 题意: 给出一张图,点有点权,边有边权 定义一条边的权值为其连接两点的异或和 定义一张图的权值为所有边的权值之和 已知部分点的点权 ...
- spoj 839 OPTM - Optimal Marks&&bzoj 2400【最小割】
因为是异或运算,所以考虑对每一位操作.对于所有已知mark的点,mark的当前位为1则连接(s,i,inf),否则连(i,t,inf),然后其他的边按照原图连(u,v,1),(v,u,1),跑最大流求 ...
- Luogu SP839 OPTM - Optimal Marks(按位最小割)
这道题和 BZOJ 2400 是一道题,不多讲了 CODE #include <cstdio> #include <cstring> #include <vector&g ...
- [SPOJ839]Optimal Marks
[SPOJ839]Optimal Marks 试题描述 You are given an undirected graph \(G(V, E)\). Each vertex has a mark wh ...
- SP839 Optimal marks(最小割)
SP839 Optimal marks(最小割) 给你一个无向图G(V,E). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记.对于边(u,v),我们定义Cost(u,v)= ...
- Optimal Marks(optimal)
Optimal Marks(optimal) 题目描述 定义无向图边的值为这条边连接的两个点的点权异或值. 定义无向图的值为无向图中所有边的值的和. 给定nn个点mm条边构成的图.其中有些点的权值是给 ...
随机推荐
- Lucene + Hadoop 分布式搜索运行框架 Nut 1.0a9转自http://www.linuxidc.com/Linux/2012-02/53113.htm
1.概述 不管程序性能有多高,机器处理能力有多强,都会有其极限.能够快速方便的横向与纵向扩展是Nut设计最重要的原则,以此原则形成以分布式并行计算为核心的架构设计.以分布式并行计算为核心的架构设计是N ...
- Landsat TM DN值转为表观反射率
日地距离计算参见<中华人民共和国气象行业标准太阳能资源评估方法>
- ubuntu11.10server 安装redis-2.6.7
1.下载安装: 1 2 3 4 5 6 cd /tmp wget http://redis.googlecode.com/files/redis-2.6.7.tar.gz tar -zxf redis ...
- 转:Selenium2.0介绍——WebDriver两种驱动浏览器的方式.
如果之前熟悉Selenium RC,理解了Selenium RC是如何工作的,那么,当第一次接触Selenium WebDriver的时候,看到WebDriver居然可以不需要指定远端服务器的IP地址 ...
- cordova插件开发-1
这是初级编,实现了js调用Android代码 首先需要编写java代码: public class AppUpdate extends CordovaPlugin { @Override public ...
- angularJs关于指令的一些冷门属性
我们使用ng的时候,经常会使用到指令,大家所熟知的属性我在这里就不介绍了,讲讲大家没怎么留意的属性 1.multiElement 这是指定指令作用区间的功能,最常用的就是ng-repeat-start ...
- UIView 面面观
原创:转载请注明出处 1.UIView: 一个视图对象控制该区域的渲染,同时也控制内容的交互. 2.UIView的功能就是:展示.渲染.交互 3.UIView 和很多其他视图控件的默认tag值是0,所 ...
- Intellij Idea搭建java web项目(问题总结)
这两天突发奇想下载了Intellij Idea,准备体验下这个传说中很强大IDE.工具下载就不多说了,网上一搜便知,博主是直接从Intellij官网下载的最新完整版,可惜的是只能使用30天,不过也差不 ...
- 基于心跳的socket长连接
http://coach.iteye.com/blog/2024444 基于心跳的socket长连接 博客分类: http socket 案例: 心跳: socket模拟网页的报文连接某个网站,创建t ...
- 畅通工程续 (dijkstra)
畅通工程续 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...