P3007 [USACO11JAN]大陆议会The Continental Cowngress(2-SAT)

2-SAT问题与Tarjan算法解析
本文深入探讨了2-SAT问题的解决方法,使用Tarjan算法进行点双连通分量缩点,通过深度优先搜索(DFS)判断法案在不同方案中的选择可能性。代码实现展示了如何处理法案与牛的表决意见,最终输出法案的可能状态。

简述:给出 n 个法案, m 头牛的意见, 每头牛有两个表决 格式为 “支持或反对某法案”, 每头牛需要至少满足一个表决, 不可能成立的话输出 IMPOSSIBLE, 否则输出方案, Y代表能, N代表不能,若是有的解中法案可以通过, 有些不能则输出“?”

 

首先不难看出这是一个2-SAT问题

那么我们先建好图然后tarjan缩点

主要的问题就是如何判断一个法案是否在不同方案里有不同选择了

这个可以直接dfs,设$i$表示该法案通过,$i'$表示该法案不通过,那么在缩完点后的DAG上跑,看看从$i$能否到$i'$以及从$i'$能否到$i$,如果一个点能到另一个点,那么很明显该点代表的状态就不存在

如果两个都可以说明是$?$,否则的话只有一种方法可以

然而我数组开小TLE了……而且还只有一个点……搞得我还以为dfs的时间复杂度不对……

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 using namespace std;
 6 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
 7 inline int read(){
 8     #define num ch-'0'
 9     char ch;bool flag=0;int res;
10     while(!isdigit(ch=getchar()))
11     (ch=='-')&&(flag=true);
12     for(res=num;isdigit(ch=getchar());res=res*10+num);
13     (flag)&&(res=-res);
14     #undef num
15     return res;
16 }
17 inline char getc(){
18     char ch;while((ch=getchar())!='Y'&&ch!='N');return ch;
19 }
20 const int N=2005,M=10005;
21 int head[N],Next[M],ver[M],tot;
22 inline void add(int u,int v){
23     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
24 }
25 int hc[N],nc[M],vc[M],tc;
26 inline void addc(int u,int v){
27     vc[++tc]=v,nc[tc]=hc[u],hc[u]=tc;
28 }
29 int dfn[N],low[N],st[N],bl[N],num,cnt,top,n,m;
30 void tarjan(int u){
31     low[u]=dfn[u]=++num,st[++top]=u;
32     for(int i=head[u];i;i=Next[i]){
33         int v=ver[i];
34         if(!dfn[v]) tarjan(v),cmin(low[u],low[v]);
35         else if(!bl[v]) cmin(low[u],dfn[v]);
36     }
37     if(dfn[u]==low[u]) for(++cnt;st[top+1]!=u;--top) bl[st[top]]=cnt;
38 }
39 int dfs(int u,int g){
40     if(u==g) return 0;
41     for(int i=hc[u];i;i=nc[i])
42     if(!dfs(vc[i],g)) return 0;
43     return 1;
44 }
45 int main(){
46 //    freopen("testdata.in","r",stdin);
47     n=read(),m=read();
48     for(int i=1;i<=m;++i){
49         int a=read(),b=getc()=='Y',c=read(),d=getc()=='Y';
50         add(a+(!b)*n,c+d*n),add(c+(!d)*n,a+b*n);
51     }
52     for(int i=1,l=n<<1;i<=l;++i) if(!dfn[i]) tarjan(i);
53     for(int i=1;i<=n;++i)
54     if(bl[i]==bl[i+n]) return puts("IMPOSSIBLE"),0;
55     for(int u=1,l=n<<1;u<=l;++u)
56     for(int i=head[u];i;i=Next[i])
57     if(bl[u]!=bl[ver[i]]) addc(bl[u],bl[ver[i]]);
58     for(int i=1;i<=n;++i){
59         int a=dfs(bl[i],bl[i+n]),b=dfs(bl[i+n],bl[i]);
60         if(a&&b) putchar('?');
61         else if(a) putchar('N');
62         else if(b) putchar('Y');
63     }
64     return 0;
65 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9786343.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值