题目大意

 

  给出一个或与表达式,每个正变量和反变量最多出现一次,询问是否存在一种方案使得每个或式中有且仅有一个变量的值为1。

解题分析

  将每个变量拆成三个点x,y,z。 y表示对应的正变量,z表示对应的反变量。

  由S向每个点的x部连一条流量为1的边,表示该变量的某个正变量或反变量的取值为1。

  由每个点的x部向y部和z部分别连一条流量为1的边,表示每个正变量和反变量仅有一个取值为1。

  若某个或式中含有某个变量,则由该变量的y部或z部向或式连一条流量为1的边。表示该变量可以使该或式的结果为1。

  由每个或式向T连一条流量为1的边,表示该或式被满足,且仅有一个变量的取值为1。

  仅仅这么连还是不够的,因为如果某个变量的正变量和反变量同时出现,那么正变量或反变量中必定有一个值为1,对应到图上则是S向该变量的x部必须有1的流量。

  所以可以向这条边添加上-1的费用,使得该变量的值优先被满足。

  跑一遍最小费用最大流,如果是满流且费用的绝对值等于必须被确定值的变量的数量,则说明可以成功满足。

  输出方案时只需遍历一下残余网络中的边,如果残余网络中没有流量则说明该变量被选择了,最后注意一下细节,确定一下对于每个变量选1还是选0。

参考程序

 #include <bits/stdc++.h>
using namespace std; #define rep(i,x,y) for (int i=x;i<=y;i++)
const int N=;
const int INF=; int n,m,S,T,sum,minC,maxF;
int lt[N*],flag[N],dis[N*],pd[N*],pre[N*],sgn[N*];
vector <int> vec[N]; struct edge{
int u,v,f,w,nt;
}eg[N*]; void add(int u,int v,int f,int w)
{
//cout<<u<<" "<<v<<" "<<f<<" "<<w<<endl;
eg[++sum]=(edge){u,v,f,w,lt[u]}; lt[u]=sum;
eg[++sum]=(edge){v,u,,-w,lt[v]}; lt[v]=sum;
} bool spfa()
{
queue <int> Q;
rep (i,S,T) dis[i]=INF,pd[i]=,pre[i]=-;
dis[S]=; pd[S]=; Q.push(S);
while (!Q.empty())
{
int u=Q.front();
for (int i=lt[u];i;i=eg[i].nt)
{
int v=eg[i].v;
if (eg[i].f>)
{
if (dis[u]+eg[i].w<dis[v])
{
dis[v]=dis[u]+eg[i].w;
pre[v]=i;
if (!pd[v])
{
Q.push(v);
pd[v]=;
}
}
}
}
pd[u]=; Q.pop();
}
return dis[T]!=INF;
}
void minCmaxF()
{
int flow;
while (spfa())
{
flow=INF;
for (int i=pre[T];~i;i=pre[eg[i].u])
flow=min(flow,eg[i].f);
for (int i=pre[T];~i;i=pre[eg[i].u])
eg[i].f-=flow,eg[i^].f+=flow;
maxF+=flow;
minC+=flow*dis[T];
}
} int main()
{
freopen("sat.in","r",stdin);
freopen("sat.out","w",stdout); cin.sync_with_stdio();
sum=; memset(lt,,sizeof(lt));
int limit=; cin>>n>>m;
S=; T=*n+m+;
rep(i,,m)
{
int num; cin>>num;
rep(j,,num)
{
int x; cin>>x;
flag[abs(x)]++;
if (x>) sgn[x]=; else sgn[x]=-;
vec[i].push_back(x);
}
}
rep(i,,n) if (flag[i]==) add(S,i,,-),limit++; else add(S,i,,);
rep(i,,n) {add(i,n+*i-,,); add(i,n+*i,,);}
rep(i,,m)
{
for (auto v:vec[i])
{
int x=v>?n+*abs(v)-:n+*abs(v);
add(x,n*+i,,);
}
add(*n+i,T,,);
}
minC=maxF=;
minCmaxF();
vector <int> ans;
if (minC==-limit && maxF==m)
{
cout<<"YES"<<endl;
for (int i=lt[S];i;i=eg[i].nt)
{
if (eg[i].f==)
{
if (sgn[eg[i].v]==) ans.push_back(); else ans.push_back();
}
else
{
if (eg[lt[eg[i].v]].f==) ans.push_back(); else ans.push_back();
}
}
for (int i=ans.size()-;i>=;i--) cout<<ans[i]<<" ";
cout<<endl;
}
else cout<<"NO"<<endl;
}

codeforces gym 100357 I (费用流)的更多相关文章

  1. CodeForces 164C Machine Programming 费用流

    Machine Programming 题目连接: http://codeforces.com/problemset/problem/164/B Descriptionww.co One remark ...

  2. Codeforces 708D 上下界费用流

    给你一个网络流的图 图中可能会有流量不平衡和流量>容量的情况存在 每调整一单位的流量/容量 需要一个单位的花费 问最少需要多少花费使得原图调整为正确(可行)的网络流 设当前边信息为(u,v,f, ...

  3. CodeForces 1187G Gang Up 费用流

    题解: 先按时间轴将一个点拆成100个点. 第一个点相当于第一秒, 第二个点相当于第二秒. 在这些点之间连边, 每1流量的费用为c. 再将图上的边也拆开. 将 u_i 向 v_i+1 建边. 将 v_ ...

  4. codeforces gym 100357 J (网络流)

    题目大意 有n种物品,m种建筑,p个人. n,m,p∈[1,20] 每种建筑需要若干个若干种物品来建造.每个人打算建造一种建筑,拥有一些物品. 主角需要通过交易来建造自己的建筑,交易的前提是对方用多余 ...

  5. codeforces gym 100357 H (DP 高精度)

    题目大意 有r*s张扑克牌,数字从1到 r,每种数字有s种颜色. 询问对于所有随机的d张牌,能选出c张组成顺子的概率和组成同花的概率. 解题分析 对于组成顺子的概率,令dp[i][j][k]表示一共选 ...

  6. codeforces gym 100357 K (表达式 模拟)

    题目大意 将一个含有+,-,^,()的表达式按照运算顺序转换成树状的形式. 解题分析 用递归的方式来处理表达式,首先直接去掉两边的括号(如果不止一对全部去光),然后找出不在括号内且优先级最低的符号.如 ...

  7. Gym - 101492I 区间限制费用流

    https://cn.vjudge.net/problem/Gym-101492I 如果用单个点代表每个区间 利用拆点来限制区间的流量的话 点是 n^2/2+m个 边是2*n^2条 但是这样会T 解法 ...

  8. Codeforces Gym 100002 E "Evacuation Plan" 费用流

    "Evacuation Plan" Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10 ...

  9. Codeforces Gym 101190M Mole Tunnels - 费用流

    题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...

随机推荐

  1. sourcetree跳过注册方法

    很人用git命令行不熟练,那么可以尝试使用sourcetree进行操作. 然鹅~~sourcetree又一个比较严肃的问题就是,很多人不会跳过注册或者操作注册. 废话不多,我们直接开始跳过注册阶段的操 ...

  2. dos 下小tip

    tip 1:日期的格式化 方法如下: Echo %Date:~0,4%%Date:~5,2%%Date:~8,2%或者Set dt=%Date:~0,4%%Date:~5,2%%Date:~8,2%E ...

  3. Jayway JsonPath实例

    开源:https://github.com/json-path/JsonPath 引入库: <dependency> <groupId>com.jayway.jsonpath& ...

  4. SQL server中的T-SQL语句

    首先点击新建查询 如下图所示 创建数据库:create database 数据库名称 使用数据库:use 数据库名称 创建表:create table 表名 ( 代码 ) 输入完成执行时需选中 如果需 ...

  5. IDEA打可执行jar包

    流程: 1. File ->Project Structure -> Artifacts -> + -> JAR -> From modules with depende ...

  6. 关于联想笔记本不能连接无线网(wifi),注销后重新登录才可以连接

    解决联想笔记本wifi问题(果果) 最近很多使用联想的朋友都遇到了这样一个问题,那就是笔记本的wifi突然不能用了,好吧,其实我个人也遇到了这个问题,但是网上貌似对这个问题并没有给出一个可以解决的办法 ...

  7. Knockout 实例

    定义见:http://baike.baidu.com/item/Knockout/18611883#viewPageContent 此处仅列举一个小例子 <p> <select da ...

  8. BZOJ1509: [NOI2003]逃学的小孩 (树形DP)

    题意:给一棵树 选三个点A,B,C 求A到B的再从B到C的距离最大值 需要满足AB的距离小于AC的距离 题解:首先树上的最大距离就想到了直径 但是被样例误导了TAT BC两点构成了直径 我一开始以为A ...

  9. vue-quill-editor + element-ui upload实现富文本图片上传

    代码贴上 <template> <div class="quill-editor-example"> <div class="box&quo ...

  10. 常用HTML5代码片段

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...