poj 3683 2-sat建图+拓扑排序输出结果
发现建图的方法各有不同,前面一题连边和这一题连边建图的点就不同,感觉这题的建图方案更好。
题意:给出每个婚礼的2个主持时间,每个婚礼的可能能会冲突,输出方案。
思路:n个婚礼,2*n个点,每组点是对称的,用O(n2)的方法判断每个点之间的关系来建图,然后通过拓扑排序输出即可。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 2002
int instack[MAXN],stack[MAXN],fa[MAXN],vis[MAXN],head[MAXN],first[MAXN];
int dfn[MAXN],low[MAXN],in[MAXN],ans[MAXN];
int a[MAXN][2],b[MAXN][2],flag[MAXN];
int n,m,tot,scnt,time,tt,top,index; struct Edge
{
int v,next;
}edge[MAXN*MAXN],e[MAXN*MAXN]; void addedge(int u,int v)
{
edge[tot].v=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void adde(int u,int v)
{
e[tt].v=v;
e[tt].next=first[u];
first[u]=tt++;
}
void print(int t)
{
int h=t/60,m=t%60;
printf("%02d:%02d",h,m);
} void tarjan(int u)
{
instack[u]=1;
stack[top++]=u;
dfn[u]=low[u]=++index;
int v;
for(int i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
scnt++;
do
{
v=stack[--top];
instack[v]=0;
fa[v]=scnt;
}while(v!=u);
}
}
void build()
{
for(int i=0;i<n;i++) //有2n个点 2*i 代表起始时间 2*i+1代表结束时间
{
for(int j=i+1;j<n;j++)
{
if((a[i][1]-a[j][0])*(a[i][0]-a[j][1])<0) //前 前冲突
{
addedge(i*2,2*j+1);
addedge(j*2,2*i+1);
}
if((a[i][1]-b[j][0])*(a[i][0]-b[j][1])<0) //前 后
{
addedge(i*2,2*j);
addedge(j*2+1,2*i+1);
}
if((b[i][1]-b[j][0])*(b[i][0]-b[j][1])<0) //后后
{
addedge(2*i+1,2*j);
addedge(2*j+1,2*i);
}
if((b[i][1]-a[j][0])*(b[i][0]-a[j][1])<0) //后前
{
addedge(2*i+1,2*j+1);
addedge(2*j,2*i);
}
}
}
}
void solve()
{
memset(dfn,0,sizeof(dfn));
memset(instack,0,sizeof(instack));
index=0;scnt=0;
for(int i=0;i<2*n;i++)
{
if(!dfn[i])
tarjan(i);
}
}
int check()
{
for(int i=0;i<n;i++)
{
if(fa[2*i]==fa[2*n+1]) //冲突
{
return 0;
}
}
return 1;
}
void topsort()
{ for(int i=0;i<scnt;)
{
for(int j=1;j<=scnt;j++)
{
if(!in[j])
{
in[j]--;ans[i++]=j;
for(int k=first[j];k!=-1;k=e[k].next)
{
int v=e[k].v;
in[v]--;
}
}
}
}
memset(flag,0,sizeof(flag));
for(int i=0;i<scnt;i++)
{
for(int j=0;j<2*n;j++)
{
if(fa[j]==ans[i]&&!flag[j^1])
{ flag[j]=1;
}
}
}
for(int i=0;i<2*n;i++)
{
if(flag[i])
{
if(i%2==0)
{
print(a[i/2][0]);printf(" ");print(a[i/2][1]);printf("\n");
}
else
{
print(b[i/2][0]);printf(" ");print(b[i/2][1]);printf("\n");
}
}
}
}
int main()
{
scanf("%d",&n);
memset(head,-1,sizeof(head));tot=0;
memset(first,-1,sizeof(first));tt=0;
for(int i=0;i<n;i++)
{
int t1,t2;
scanf("%d:%d",&t1,&t2);
a[i][0]=t1*60+t2;
scanf("%d:%d",&t1,&t2);
b[i][1]=t1*60+t2;
scanf("%d",&time);
a[i][1]=a[i][0]+time;
b[i][0]=b[i][1]-time;
}
build();
solve();
if(!check())printf("NO\n");
else
{
memset(in,0,sizeof(in));
for(int i=0;i<2*n;i++)
{
int v;
for(int j=head[i];j!=-1;j=edge[j].next)
{
v=edge[j].v;
if(fa[i]!=fa[v])
{
adde(fa[v],fa[i]);
in[fa[i]]++;
}
}
}
printf("YES\n");
topsort();
} return 0;
}
poj 3683 2-sat建图+拓扑排序输出结果的更多相关文章
- HDU4857——逃生(反向建图+拓扑排序)(BestCoder Round #1)
逃生 Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会 ...
- POJ3687——Labeling Balls(反向建图+拓扑排序)
Labeling Balls DescriptionWindy has N balls of distinct weights from 1 unit to N units. Now he tries ...
- BZOJ_4383_[POI2015]Pustynia_线段树优化建图+拓扑排序
BZOJ_4383_[POI2015]Pustynia_线段树优化建图+拓扑排序 Description 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息 ...
- 牛客多校第四场 J.Hash Function(线段树优化建图+拓扑排序)
题目传送门:https://www.nowcoder.com/acm/contest/142/J 题意:给一个hash table,求出字典序最小的插入序列,或者判断不合法. 分析: eg.对于序列{ ...
- hdu 4857 逆向建图+拓扑排序 ***
题意:糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行.现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有 ...
- HUD2647 Reward_反向建图拓扑排序
HDU2647 Reward 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647 题意:老板要发奖金了,有n个人,给你m对数,类似a b,这样的一对 ...
- 逃生 HDU 4857(反向建图 + 拓扑排序)
逃生 链接 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必 ...
- [POI2015][bzoj4383] Pustynia [线段树优化建图+拓扑排序]
题面 bzoj权限题传送门 luogu传送门 思路 首先,这个题目显然可以从所有小的点往大的连边,然后如果没环就一定可行,从起点(入读为0)开始构造就好了 但是问题来了,如果每个都连的话,本题中边数是 ...
- BZOJ 5496: [2019省队联测]字符串问题 (后缀数组+主席树优化建图+拓扑排序)
题意 略 分析 考场上写了暴力建图40分溜了-(结果只得了30分) 然后只要优化建边就行了 首先给出的支配关系无法优化,就直接A向它支配的B连边. 考虑B向以B作为前缀的所有A连边,做一遍后缀数组,两 ...
随机推荐
- 在Mac OS 下 build Tesseract4.0 源码并在命令行中使用
作者电脑:Mac Mini 系统信息:OS X EI Capitan 10.11.6 Tesseract4.0github地址:https://github.com/tesseract-ocr/tes ...
- MapReduce框架Hadoop应用(一)
Google对其的定义:MapReduce是一种变成模型,用于大规模数据集(以T为级别的数据)的并行运算.用户定义一个map函数来处理一批Key-Value对以生成另一批中间的Key-Value对,再 ...
- Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. For example, given n = 3, a solution set is: "((()))", "(()())", "(())()", "()(())", "()()()"
思路:采用递归的思想,当左括号数大于右括号数时可以加左或者右括号,否则只能加左括号,当左括号数达到n时,剩下全部.不过,每一个方法的调用都会产生一个栈帧,每执行一个方法就会出现压栈操作,所以采用递归的 ...
- 利用C#进行Socket通信编程之二:一个实例
本文转载自: http://blog.csdn.net/huangxinfeng/article/details/4967629/
- JavaScript 开发总结(一)
数据类型:JavaScript定义的数据类型有字符串.数字.布尔.数组.对象.Null.Undefined,但typeof有区分可判别的数据分类是number.string.boolean.objec ...
- 总结jq的一些特效
Jquery代码总结 1.轮播图: <script src="jquery-1.8.3.min.js"></script><script> ...
- Shell - 简明Shell编程
本文是对Shell脚本编程的总结和回顾,所有涉及的脚本均已做了基本的调试和验证. [toc] 测试环境信息 [root@CentOS7 ~]# uname -a Linux CentOS7 3.10. ...
- win7自动关机方法
远程操控电脑的时候&爬虫的时候所需2333 win+R输入cmd,进入cmd. 输入shutdown 然后输入shutdown -s -t 3600 设置3600秒(1小时)后关机,大家可以根 ...
- IPython使用学习笔记
学习<利用python进行数据分析>第三章 IPython:一种交互式计算和开发环境的笔记,共享给大家,同时为自己作为备忘用. 安装ipython用pip即可.ps.博主用的是win7系统 ...
- web前端+javascript+h5电子书籍和实战分享
有很多前端伙伴们学习前端很多了,但是如何能成为优秀的程序员呢,前端必学的知识点相信学习前端的伙伴们心里都非常清楚.主要的三要素包括HTML.CSS和JavaScript.那么学好JavaScript是 ...