图论(网络流):SPOJ OPTM - Optimal Marks
OPTM - Optimal Marks
You are given an undirected graph G(V, E). Each vertex has a mark which is an integer from the range [0..231 – 1]. Different vertexes may have the same mark.
For an edge (u, v), we define Cost(u, v) = mark[u] xor mark[v].
Now we know the marks of some certain nodes. You have to determine the marks of other nodes so that the total cost of edges is as small as possible.
Input
The first line of the input data contains integer T (1 ≤ T ≤ 10) - the number of testcases. Then the descriptions of T testcases follow.
First line of each testcase contains 2 integers N and M (0 < N <= 500, 0 <= M <= 3000). N is the number of vertexes and M is the number of edges. Then M lines describing edges follow, each of them contains two integers u, v representing an edge connecting u and v.
Then an integer K, representing the number of nodes whose mark is known. The next K lines contain 2 integers u and p each, meaning that node u has a mark p. It’s guaranteed that nodes won’t duplicate in this part.
Output
For each testcase you should print N lines integer the output. The Kth line contains an integer number representing the mark of node K. If there are several solutions, you have to output the one which minimize the sum of marks. If there are several solutions, just output any of them.
Example
Input:
1
3 2
1 2
2 3
2
1 5
3 100 Output:
5
4
100 COGS上AC了,这里花46分钟买了个教训。
SPOJ:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int INF=;
const int maxn=;
const int maxm=;
int cnt,fir[maxn],to[maxm],nxt[maxm],cap[maxm];
void addedge(int a,int b,int c){
nxt[++cnt]=fir[a];
fir[a]=cnt;
cap[cnt]=c;
to[cnt]=b;
} queue<int>q;
int dis[maxn];
bool BFS(int s,int t){
dis[t]=;q.push(t);
while(!q.empty()){
int x=q.front();q.pop();
for(int i=fir[x];i;i=nxt[i])
if(!dis[to[i]]){
dis[to[i]]=dis[x]+;
q.push(to[i]);
}
}
return dis[s];
} int fron[maxn];
int gap[maxn],path[maxn];
int ISAP(int s,int t){
if(!BFS(s,t))return ;
for(int i=s;i<=t;i++)++gap[dis[i]];
for(int i=s;i<=t;i++)fron[i]=fir[i];
int p=s,ret=,f;
while(dis[s]<=t+){
if(p==t){
f=INF;
while(p!=s){
f=min(f,cap[path[p]]);
p=to[path[p]^];
}
ret+=f;p=t;
while(p!=s){
cap[path[p]]-=f;
cap[path[p]^]+=f;
p=to[path[p]^];
}
}
int &ii=fron[p];
for(;ii;ii=nxt[ii])
if(cap[ii]&&dis[p]==dis[to[ii]]+)
break;
if(ii)
path[p=to[ii]]=ii;
else{
if(--gap[dis[p]]==)break;
int minn=t+;
for(int i=fir[p];i;i=nxt[i])
if(cap[i])minn=min(minn,dis[to[i]]);
++gap[dis[p]=minn+];ii=fir[p];
if(p!=s)p=to[path[p]^];
}
}
return ret;
} void Init(){
memset(fir,,sizeof(fir));
memset(dis,,sizeof(dis));
memset(gap,,sizeof(gap));
cnt=;
} int n,m,T;
long long a[maxn],w[maxn];
int E[maxm][],fa[maxn];
int Find(int x){
return fa[x]==x?x:fa[x]=Find(fa[x]);
} int vis[maxn];
void DFS(int x,int d){
vis[x]=;a[x]|=d;
for(int i=fir[x];i;i=nxt[i])
if(cap[i]&&!vis[to[i]])
DFS(to[i],d);
} long long Solve(){
int s=,t=n+;
long long ret=;
for(int k=;k<=;k++){
Init();
for(int i=;i<=n;i++)
if(Find(i)==&&w[i]>=){
if(w[i]>>k&){
addedge(s,i,INF);
addedge(i,s,);
}
else{
addedge(i,t,INF);
addedge(t,i,);
}
}
for(int i=;i<=m;i++)
if(Find(E[i][])==){
addedge(E[i][],E[i][],);
addedge(E[i][],E[i][],);
}
ret+=(1ll<<k)*ISAP(s,t);
memset(vis,,sizeof(vis));
DFS(s,1ll<<k);
}
return ret;
} int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
for(int j=;j<=;j++)
scanf("%d",&E[i][j]); int u,v,k;
scanf("%d",&k);
memset(w,-,sizeof(w));
memset(a,,sizeof(a));
while(k--){
scanf("%d",&u);
scanf("%lld",&w[u]);
} for(int i=;i<=n;i++)
fa[i]=w[i]!=-?:i; for(int i=;i<=m;i++){
u=Find(E[i][]);
v=Find(E[i][]);
if(u>v)swap(u,v);
if(u!=v)fa[v]=u;
}
Solve();
for(int i=;i<=n;i++)
if(w[i]<)
printf("%lld\n",a[i]);
else
printf("%lld\n",w[i]);
}
return ;
}
图论(网络流):SPOJ OPTM - Optimal Marks的更多相关文章
- 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 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. ...
- SPOJ 839 OPTM - Optimal Marks (最小割)(权值扩大,灵活应用除和取模)
http://www.spoj.com/problems/OPTM/ 题意: 给出一张图,点有点权,边有边权 定义一条边的权值为其连接两点的异或和 定义一张图的权值为所有边的权值之和 已知部分点的点权 ...
- 【bzoj2400】Spoj 839 Optimal Marks 网络流最小割
题目描述 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其余的点的值由你 ...
- spoj 839 OPTM - Optimal Marks&&bzoj 2400【最小割】
因为是异或运算,所以考虑对每一位操作.对于所有已知mark的点,mark的当前位为1则连接(s,i,inf),否则连(i,t,inf),然后其他的边按照原图连(u,v,1),(v,u,1),跑最大流求 ...
- SPOJ839 OPTM - Optimal Marks
传送门 闵神讲网络流应用的例题,来水一水 要写出这道题,需要深入理解两个概念,异或和最小割. 异或具有相对独立性,所以我们把每一位拆开来看,即做大概$32$次最小割.然后累加即可. 然后是最小割把一张 ...
- BZOJ2400: Spoj 839 Optimal Marks
Description 定义无向图中的一条边的值为:这条边连接的两个点的值的异或值. 定义一个无向图的值为:这个无向图所有边的值的和. 给你一个有n个结点m条边的无向图.其中的一些点的值是给定的,而其 ...
- spoj 839 Optimal Marks(二进制位,最小割)
[题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=17875 [题意] 给定一个图,图的权定义为边的两端点相抑或值的 ...
随机推荐
- 一次项目中用到的php函数总结
最近做的一个项目,我把做的过程中用到的php函数总结一下.以后遇到类似的不用百度,直接看自己总结的就好了.都是一些简单基础的函数,随手记下.方便以后学习. 1.array_sum() 返回数组中的所有 ...
- Android开发常见错误类型一览表
这是我的第一个博客,我会一直添加我在Android开发中遇到的错误,用来记录我开发中踩过的那些坑 ------------------------分割线------------------------ ...
- SimpleDateFormat使用详解
http://blog.csdn.net/gubaohua/article/details/575488 public class SimpleDateFormat extends DateForma ...
- PHP 进行统一邮箱登陆的代理实现(swoole)
在工作的过程中,经常会有很多应用有发邮件的需求,这个时候需要在每个应用中配置smtp服务器.一旦公司调整了smtp服务器的配置,比如修改了密码等,这个时候对于维护的人员来说要逐一修改应用中smtp的配 ...
- 常用的dos命令之简略总结
Dos常用命令 一.基础命令 1 dir 无参数:查看当前所在目录的文件和文件夹. /s:查看当前目录已经其所有子目录的文件和文件夹. /a:查看包括隐含文件的所有文件. /ah:只显示出 ...
- iOS9适配中出现的一些常见问题
本文主要是说一些iOS9适配中出现的坑,如果只是要单纯的了解iOS9新特性可以看瞄神的开发者所需要知道的 iOS 9 SDK 新特性.9月17日凌晨,苹果给用户推送了iOS9正式版,随着有用户陆续升级 ...
- ios strong weak 的区别 与 理解
先一句话总结:strong类保持他们拥有对象的活着,weak类他们拥有的对象被人家一牵就牵走,被人家一干就干死.(strong是一个好大哥所以strong,呵呵,weak是一个虚大哥所以weak,呵呵 ...
- SGU 200.Cracking RSA(高斯消元)
时间限制:0.25s 空间限制:4M 题意: 给出了m(<100)个数,这m个数的质因子都是前t(<100)个质数构成的. 问有多少个这m个数的子集,使得他们的乘积是完全平方数. Solu ...
- windows编程中 一些前缀区分 IDR和IDD
IDC_:控件的ID命名前缀(Control) IDM_:菜单的ID命名前缀(Menu) IDD_:对话框的ID命名前缀(Dialog) IDR_:资源的ID命名前缀(Resource) IDS_:字 ...
- php之递归调用,递归创建目录
/* 递归自身调用自身,每次调用把问题简化,直到问题解决 即:把大的任务拆成相同性质的多个小任务完成 */ /* function recsum($n){ if($n>1){ return $n ...