题目链接:点击查看

题目大意:给出一个由 n 个点和 m 条边组成的图,有 k 个点初始时就有权值 w[ i ],现在问如何给剩下的节点赋值,使得整张图的总权值和最小,每条边的权值为:w( u , v ) = w[ u ] xor w[ v ]

题目分析:因为异或运算属于位运算,所以对于每一位来说其贡献都是相互独立的,可以分开之后分别计算

这样问题就转换成了,对于那些未赋值的位置来说,选择 0 或 1 将其赋值,因为每个位置的取值只有两种选择,又是一种最优性问题,不难想到最小割

建图思路也比较简单:

  1. st -> 已经确定答案了,且当前位置为 1 的点,流量为 inf
  2. 原图,流量为 1
  3. 已经确定了答案,且当前位置为 0 的点 -> ed,流量为 inf

这样求完最小割后,与 st 在一个联通块中的点显然赋值为 1 是更优的,同理与 ed 在一个联通块中的点需要赋值为 0

代码:

//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
#include<unordered_map>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=510;pair<int,int>e[3100];struct Edge
{int to,w,next;
}edge[N*N];//边数int head[N],cnt,n,m;unsigned int ans[N];bool vis[N],book[N];void addedge(int u,int v,int w)
{edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].w=0;//反向边边权设置为0edge[cnt].next=head[v];head[v]=cnt++;
}int d[N],now[N];//深度 当前弧优化bool bfs(int s,int t)//寻找增广路
{memset(d,0,sizeof(d));queue<int>q;q.push(s);now[s]=head[s];d[s]=1;while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(d[v])continue;if(!w)continue;d[v]=d[u]+1;now[v]=head[v];q.push(v);if(v==t)return true;}}return false;
}int dinic(int x,int t,int flow)//更新答案
{if(x==t)return flow;int rest=flow,i;for(i=now[x];i!=-1&&rest;i=edge[i].next){int v=edge[i].to;int w=edge[i].w;if(w&&d[v]==d[x]+1){int k=dinic(v,t,min(rest,w));if(!k)d[v]=0;edge[i].w-=k;edge[i^1].w+=k;rest-=k;}}now[x]=i;return flow-rest;
}void init()
{memset(now,0,sizeof(now));memset(head,-1,sizeof(head));memset(book,false,sizeof(book));cnt=0;
}int solve(int st,int ed)
{int ans=0,flow;while(bfs(st,ed))while(flow=dinic(st,ed,inf))ans+=flow;return ans;
}void dfs(int u)
{book[u]=true;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if(book[v])continue;if(edge[i].w)dfs(v);}
}void solve(int bit)
{init();int st=N-1,ed=st-1;for(int i=1;i<=n;i++){if(!vis[i])continue;if((ans[i]>>bit)&1)addedge(st,i,inf);elseaddedge(i,ed,inf);}for(int i=1;i<=m;i++){int u,v;tie(u,v)=e[i];addedge(u,v,1);addedge(v,u,1);}solve(st,ed);dfs(st);for(int i=1;i<=n;i++)if(book[i])ans[i]|=(1u<<bit);
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.ans.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);int w;cin>>w;while(w--){memset(ans,0,sizeof(ans));memset(vis,false,sizeof(vis));scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)scanf("%d%d",&e[i].first,&e[i].second);int k;scanf("%d",&k);while(k--){int x;scanf("%d",&x);scanf("%u",&ans[x]);vis[x]=true;}for(int i=0;i<=31;i++)solve(i);for(int i=1;i<=n;i++)printf("%u\n",ans[i]);}return 0;
}

SPOJ - OPTM Optimal Marks(进制拆分+最小割)相关推荐

  1. bzoj 2400: Spoj 839 Optimal Marks(最小割)

    2400: Spoj 839 Optimal Marks Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 873  Solved: 330 [Subm ...

  2. 2400: Spoj 839 Optimal Marks

    2400: Spoj 839 Optimal Marks Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 618  Solved: 227 [Subm ...

  3. HihoCoder - 1873 Frog and Portal(构造+进制拆分)

    题目链接:点击查看 题目大意:给出 200 个石头,有一只青蛙要从第 0 个石头跳到第 200 个石头,每次只能跳 1 步或 2 步,显然可行的方案数是一个斐波那契数列,现在可以在两个石头上放置传送门 ...

  4. 【BZOJ-2400】Spoj839Optimal Marks 最小割 + DFS

    2400: Spoj 839 Optimal Marks Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 567  Solved: 202 [Subm ...

  5. 1192. [HNOI2006]鬼谷子的钱袋【进制】

    Description 鬼谷子非常聪明,正因为这样,他非常繁忙,经常有各诸侯车的特派员前来向他咨询时政.有一天,他在咸阳游历的时候,朋友告诉他在咸阳最大的拍卖行(聚宝商行)将要举行一场拍卖会,其中有一 ...

  6. 《算法零基础100讲》(第20讲) 进制转换(二) - 进阶[C语言题解]

    文章目录 一. 知识普及 1.1 atoi 1.2 log 1.3 pow 1.4 floor 二. 进阶题解 168. Excel表列名称 171. Excel 表列序号 483. 最小好进制 一. ...

  7. Python进制转换的完全实现——2/10/16进制原/补码互转

    一.需要转换的几种情况 不带符号位的整数 2进制 10进制 16进制 2进制 – bin2dec() bin2hex() 10进制 dec2bin() – dec2hex() 16进制 hex2bin ...

  8. [解题报告](第20讲) 进制转换(二) - 进阶

    零.写在前面 这是打卡的第二十天,今天题目还是有点难度的,不过就是题量下来了,可以沉淀一下之前的题目了,主要知识点在<算法零基础100讲>(第20讲) 进制转换(二) - 进阶https: ...

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

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

最新文章

  1. Python 各种运行错误(如:SyntaxError :invalid syntax)
  2. Hadoop中Namenode单点故障的解决方案及详细介绍
  3. [BZOJ1503][NOI2004]郁闷的出纳员 无旋Treap
  4. 对现有的所能找到的DDOS代码(攻击模块)做出一次分析----自定义攻击篇
  5. array关于map,reduce,filter的用法
  6. 数据分箱6——分箱结果进行WOE转化
  7. 自动刷新徐小明股市直播内容
  8. 从零开始系类——模拟电子技术
  9. python怎样批量修改文件大小_使用python对文件夹下的照片进行批量修改尺寸
  10. 使用INT4/INT类型替换INT8/BIGINT类型能够节省多少磁盘空间?
  11. Olympic Class Ships【奥林匹克级邮轮】
  12. Python - 【珍藏】知识清单及文章链接
  13. Kinect(XBOX360)相机在ROS下标定
  14. 去哪儿网BI平台建设演进与实践
  15. 虚拟现实与模拟仿真---unity
  16. pytorch椎骨检测之分类模型
  17. 计算机鼠标不会动,为什么鼠标突然不动了 有什么解决方法
  18. 如何在eLance,oDesk或Guru.com等外包平台上赢得任何项目?
  19. 锁屏后微信显示无法连接服务器,手机锁屏后微信收不到信息是怎么回事
  20. Select字段名和Select*

热门文章

  1. mysql 指定目录_mysql 更改默认数据目录
  2. php对象json,php 把对象转化为json
  3. MySQL单行函数分类
  4. MySQL高级 - 案例 - 系统性能优化分析
  5. RabbitMQ交换机简介
  6. 对HTTP/2 支持
  7. 如果传输的文件过大怎么办
  8. Bean的依赖注入方式
  9. restTemplate 传递map
  10. JAVA生成随机字符串方法