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连边,做一遍后缀数组,两 ...
随机推荐
- java_final修饰符
1.修饰变量时,表示该变量一旦获得初始值就不可改变 final修饰的成员变量必须由程序员显示地指定初始值,系统不会进行隐式初始化 类变量:必须在初始化块中指定初始值或声明该类变量时指定初始值 实例变量 ...
- ++i,i++和i += 1的区别
++i,i++和i += 1的区别 单条语句:i++;.++i;和 i += 1;等价. int i = 0; ++i; // 或者i++;或者i += 1; cout << i < ...
- 最小生成树详解 prim+ kruskal代码模板
最小生成树概念: 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边. 最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里 ...
- RSA加密解密及RSA加签验签
RSA安全性应用场景说明 在刚接触RSA的时候,会混淆RSA加密解密和RSA加签验签的概念.简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解 ...
- 常用颜色RGB、灰度值
128/0/0 深红 255/0/0 红 255/0/255 粉红 255/153/204 玫瑰红 153 ...
- Sublime text 3搭建Python开发环境
前辈们说的已经很多了,但是自己依旧会出现各种问题,写篇日志记录这次的搭建经验. 1.安装python,我用的是python3.5,可以上官网下载 2.安装Sublime text 3,可以上官网下载 ...
- vue模板的几种写法及变化
第一种: 2+版本支持,1+版本支持 <script> <template id="aaa"> <h1>我是组件2</h1> < ...
- Appium入门示例(Java)
一.使用Eclipse直接创建案例工程 1.打开Eclipse,[File]-->[New]-->[Project] 2.选择[Java Project]-->[Next] 3.输入 ...
- DB2的日志理解难点
在DB2中最早的recovery时间点,是由minBuffLsn 和 lowTranLsn 的最小值决定的. minBuffLsn: represents the oldest change to a ...
- WebService核心文件【web-config.wsdd】调用操作
WebService核心文件[server-config.wsdd]详解及调用示例 作者:玛莎拉蒂-小贱人 一.准备工作 导入需要的jar包: 二.配置web.xml 在web工程的web.xml中添 ...