ural1382 直接套用 2SAT模板

缩点 拓扑排序。。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
//2SAT问题 准确判断矛盾边 不必考虑推出的边是否存在矛盾!!
using namespace std;
const int maxn=(1000+1);
vector<int>po[maxn*2],ps[maxn*2],strong[maxn*2];
bool vis[maxn*2],added[maxn*2][maxn*2];
int n,a[maxn],b[maxn],c[maxn],tot=0,color[maxn*2],du[maxn*2],point[maxn*2];
stack<int>s;
void add(int b,int a)
{
if(added[b][a])return;
else added[b][a]=true;
po[a].push_back(b);
ps[b].push_back(a);
}
void dfs1(int cur,int fa)
{
vis[cur]=true;
for(int i=0;i<po[cur].size();i++)
{
int np=po[cur][i];
if(np==fa||vis[np])continue;
dfs1(np,cur);
}
s.push(cur);
}
void dfs2(int cur,int co,int fa)
{
strong[co].push_back(cur);
color[cur]=co;
for(int i=0;i<ps[cur].size();i++)
{
int np=ps[cur][i];
if(np==fa||(color[np]))continue;
dfs2(np,co,cur);
}
}
void strongconnect()
{
memset(vis,0,sizeof(vis));memset(color,0,sizeof(color));
for(int i=1;i<=n*2;i++)
if(!vis[i])dfs1(i,-1);
tot=1;
while(!s.empty())
{
int np=s.top();
s.pop();
if(color[np])continue;
dfs2(np,tot++,-1);
}
}
bool cmp(int a,int b)
{
return du[a]<du[b];
}
int topo(int ans[])
{
for(int i=1;i<tot;i++)
point[i]=i;
bool anss=1;
for(int i=1;i<tot;i++)
{
sort(point+i,point+tot,cmp);
int np=point[i];
if(du[np]>0)return -1;
if(du[np]==du[point[i+1]]&&i+1<tot)anss=0;
ans[i]=np;
for(int j=0;j<ps[np].size();j++)
du[ps[np][j]]--;
}
}
int main()
{
freopen("t.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&a[i],&b[i],&c[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j)continue;
if(a[i]==a[j])
{
add(j*2,i*2-1);
add(i*2,j*2-1);
}
if(i==b[j])
{
add(i*2,j*2);
add(j*2-1,i*2-1);
}
if(b[i]==b[j])
{
add(i*2-1,j*2);
add(j*2-1,i*2);
}
if((a[i]==c[j]&&i!=b[j]))
{
add(i*2,j*2);
add(j*2-1,i*2-1);
}
}
strongconnect(); for(int i=1;i<tot;i++)
{
memset(vis,0,sizeof(vis));
ps[i].clear();
for(int j=0;j<strong[i].size();j++)
{
int np=strong[i][j];
for(int k=0;k<po[np].size();k++)
{
int nc=color[po[np][k]];
if(nc==i)continue;
if(vis[nc]){continue;}
else{vis[nc]=true;ps[i].push_back(nc);du[nc]++;}
}
}
}
int ans[maxn*2];
topo(ans);
int anss[maxn];
for(int i= tot-1;i>=1;i--)
{
int np=ans[i];
for(int i=0;i<strong[np].size();i++)
{
int npp=strong[np][i];
if(anss[(npp+1)/2]==0) anss[((npp+1)/2)]=(npp+1)%2+1;
}
}
for(int i=1;i<n;i++)
printf("%d ",anss[i]);
printf("%d\n",anss[n]);
return 0;
}

  

最新文章

  1. springMVC接受JSON异常
  2. React Native MAC上环境搭建笔记
  3. MySQL 系列(五) 多实例、高可用生产环境实战
  4. htnl中的遮罩层以及定位方式
  5. Reflector反编译WinForm程序重建项目资源和本地资源
  6. ubuntu(16.04.01)学习-day2--高级命令
  7. php date操作
  8. Linux C 简易聊天室
  9. 阿里云oss总是提示SignatureDoesNotMatch错误怎么办
  10. 从SAP顾问猝死事件谈顾问加班
  11. Struts2学习笔记(六)——Action处理请求参数
  12. vue 自定义组件 v-model双向绑定、 父子组件同步通信
  13. 微信小程序实现按首字母检索城市列表
  14. bzoj3437小P的牧场 斜率优化dp
  15. RTB--Real TimeBidding模式的互联网广告(实时竞价的广告投放)
  16. 南邮攻防训练平台逆向第四题WxyVM
  17. pymysql连接数据库,读取表内容
  18. Java时间串获取(格式:yyyyMMddHHmmss)
  19. python glob 模块
  20. Android学习路-Android Studio的工程目录

热门文章

  1. 4_蒙特卡罗算法求圆周率PI
  2. Maximun product
  3. AutoMapper的使用在NET core中的使用记录
  4. 从PDF复制到word(换行问题)
  5. iPhone安装ipa的方法(iTunes,PP助手)
  6. HDU 4960 (水dp)
  7. Jquery EasyUI动态生成Tab
  8. Java DynamoDB 增加、删除、修改、查询
  9. [转]一个完整的Installshield安装程序实例
  10. 搭建ELK收集PHP的日志