首页 > 其他分享 >闲话 10.10

闲话 10.10

时间:2024-10-10 12:11:39浏览次数:9  
标签:int 闲话 v1 v2 dfn low Wadd 10.10

想到什么写什么


昨晚

CTH(大喊):HDK!

HDK(大喊):CTH!

CTH(愣了一下):干啥?


2-SAT

定义

给出若干个形如 \(a\lor b\) 的限制条件,询问是否有满足条件的一组解。

人话:给出 \(n\) 个集合,每个集合两个元素,再给定若干个限制条件 \(\left \langle a,b\right \rangle\) 表示 \(a\) 与 \(b\) 矛盾,询问在这 \(n\) 个集合中各选一个能否满足所有限制条件。

思路

考虑转化限制条件。已知 \(a\lor b\) 为真,则当 \(\lnot a\) 为真时 \(b\) 必为真,简单推一下可得:

\[\lnot a\to b,\lnot b \to a \]

这样模型就构建出来了,我们可以将其转化成图来做。

考虑这样连边的含义,若起点为真则终点必为真,那么若成环则表示这些点同时为真或假,我们可以用 tarjan 将它们缩成一个点。

判断有无解的办法是看 \(a\) 与 \(\lnot a\) 的点是否缩成同一个点,若是则显然无解,否则有解。

若要输出方案,一种合法的构造是判断 \(a\) 与 \(\lnot a\) 缩点的先后,先缩为真。

实现

【模板】2-SAT

直接按思路做即可。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch = getchar();lx x = 0 , f = 1;
	for(;ch<'0'||ch>'9';ch = getchar()) if(ch == '-') f = -1;
	for(;ch>= '0' && ch<= '9';ch = getchar()) x = (x<<3) + (x<<1) + (ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define pil pair<int, ll>
#define fi first
#define se second
const int Ratio = 0;
const int N = 2e6 + 5;
int n, m;
int dfn[N], low[N], tot, bl[N], num;
int hh[N], to[N << 1], ne[N << 1], cnt;
stack<int> st;
namespace Wisadel
{
    void Wadd(int u, int v)
    {
        to[++cnt] = v;
        ne[cnt] = hh[u];
        hh[u] = cnt;
    }
    void Wtarjan(int u)
    {
        dfn[u] = low[u] = ++tot, st.push(u);
        for(int i = hh[u]; i != -1; i = ne[i])
        {
            int v = to[i];
            if(!dfn[v])
            {
                Wtarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else if(!bl[v]) low[u] = min(low[u], dfn[v]);
        }
        if(dfn[u] == low[u])
        {
            ++num;
            while(st.size())
            {
                int zc = st.top(); st.pop();
                bl[zc] = num;
                if(zc == u) break;
            }
        }
    }
    short main()
    {
        // freopen(".in", "r", stdin) , freopen(".out", "w", stdout);
        n = qr, m = qr;
        memset(hh, -1, sizeof hh);
        fo(i, 1, m)
        {
            int x = qr, v1 = qr, y = qr, v2 = qr;
            if(v1 && v2) Wadd(x + n, y), Wadd(y + n, x);
            if(v1 && !v2) Wadd(x + n, y + n), Wadd(y, x);
            if(!v1 && v2) Wadd(x, y), Wadd(y + n, x + n);
            if(!v1 && !v2) Wadd(x, y + n), Wadd(y, x + n);
        }
        fo(i, 1, 2 * n) if(!dfn[i]) Wtarjan(i);
        bool can = 1;
        fo(i, 1, n) if(bl[i] == bl[i + n]){can = 0; break;}
        if(!can) puts("IMPOSSIBLE");
        else
        {
            puts("POSSIBLE");
            fo(i, 1, n) printf("%d ", (bl[i] < bl[i + n]));
        }
        return Ratio;
    }
}
int main(){return Wisadel::main();}

例题

[JSOI2010] 满汉全席

每一种食材不是满就是汉,比较能看出来是 2-SAT,看出来后就是纯板子了。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{
	char ch = getchar();lx x = 0 , f = 1;
	for(;ch<'0'||ch>'9';ch = getchar()) if(ch == '-') f = -1;
	for(;ch>= '0' && ch<= '9';ch = getchar()) x = (x<<3) + (x<<1) + (ch^48);
	return x*f;
}
#undef lx
#define qr qr()
#define pii pair<int, int>
#define pil pair<int, ll>
#define fi first
#define se second
const int Ratio = 0;
const int N = 1e5 + 5;
int m, n;
int dfn[N], low[N], tot, bl[N], num;
int hh[N], to[N << 1], ne[N << 1], cnt;
stack<int> st;
namespace Wisadel
{
    void Wadd(int u, int v)
    {
        to[++cnt] = v;
        ne[cnt] = hh[u];
        hh[u] = cnt;
    }
    void Wtarjan(int u)
    {
        dfn[u] = low[u] = ++tot, st.push(u);
        for(int i = hh[u]; i != -1; i = ne[i])
        {
            int v = to[i];
            if(!dfn[v])
            {
                Wtarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else if(!bl[v]) low[u] = min(low[u], dfn[v]);
        }
        if(dfn[u] == low[u])
        {
            num++;
            while(st.size())
            {
                int zc = st.top(); st.pop();
                bl[zc] = num;
                if(zc == u) break;
            }
        }
    }
    short main()
    {
        // freopen(".in", "r", stdin) , freopen(".out", "w", stdout);
        int T = qr;
        while(T--)
        {
            n = qr, m = qr;
            cnt = num = tot = 0;
            memset(hh, -1, sizeof hh);
            memset(bl, 0, sizeof bl);
            memset(dfn, 0, sizeof dfn);
            fo(i, 1, m)
            {
                string s1, s2; cin >> s1 >> s2;
                int l1 = s1.size(), l2 = s2.size();
                int v1 = 0, v2 = 0;
                fo(j, 1, l1 - 1) v1 = v1 * 10 + s1[j] - '0';
                fo(j, 1, l2 - 1) v2 = v2 * 10 + s2[j] - '0';
                if(s1[0] == 'm' && s2[0] == 'm') Wadd(v1 + n, v2), Wadd(v2 + n, v1);
                if(s1[0] == 'm' && s2[0] == 'h') Wadd(v1 + n, v2 + n), Wadd(v2, v1);
                if(s1[0] == 'h' && s2[0] == 'm') Wadd(v1, v2), Wadd(v2 + n, v1 + n);
                if(s1[0] == 'h' && s2[0] == 'h') Wadd(v1, v2 + n), Wadd(v2, v1 + n);
            }
            fo(i, 1, 2 * n) if(!dfn[i]) Wtarjan(i);
            bool can = 1;
            fo(i, 1, n) if(bl[i] == bl[i + n]){can = 0; break;}
            if(!can) puts("BAD");
            else puts("GOOD");
        }
        return Ratio;
    }
}
int main(){return Wisadel::main();}

发现要用到 tarjan,但是大部分忘了,所以复习。

Tarjan 求点双,缩点

感觉现阶段再看 tarjan 好理解了不少。

\(dfn_u\) 为点 \(u\) 的 dfs 序,\(low_u\) 是点 \(u\) 能通过返祖边返回到的最小的节点的 dfs 序。

后面仙姑。

标签:int,闲话,v1,v2,dfn,low,Wadd,10.10
From: https://www.cnblogs.com/Ratio-Yinyue1007/p/18456050

相关文章

  • UpdatePack7R2 24.10.10 参数详细说明及示例
    UpdatePack7R224.10.10使用示例以下是一些使用UpdatePack7R2的示例命令:自动安装所有更新,包括InternetExplorer11,并重启计算机:CopyCodeUpdatePack7R2.exe/ie11/silent/reboot隐藏所有现有产品的更新,不更改InternetExplorer的版本,并且不重启计算机:CopyCode......
  • 「闲话」CSP 集训记梦
    一个不写闲话的oier不能证明他是一个oier其实写这个是因为10.5晚上做梦了,所以记录一下建议跳过9.28和10.1部分9.28上午模拟赛。T1一开始搞了个贪心假做法,发现过了大样例,但显然不对吧!也不会其他的解法,先交了一发。然后开始写暴力拍了一手,两千组拍出了个Wa的,手......
  • 【2024.10.4 闲话】0/99+
    今日推歌:没有。明天可能有。今日set:也没有。话说应该没人知道set是什么吧,总之不是std::set。[ARC176E]MaxVector给你两个长度为\(N\)的正整数序列:\(X=(X_1,X_2,\dots,X_N)\)和\(Y=(Y_1,Y_2,\dots,Y_N)\)。此外,你还得到\(M\)个长度为\(N\)的正整数序列。第\(......
  • 【闲话】高一上运动会
    心跳节拍·弥梦离“加油,加油!”虽然没有上场,但记忆也为本次运动会的举办做出了许多努力!想喝矿泉水的话,就请记忆帮你拿一瓶吧!活力四射·超神龙女代表着竞技的绿茵场上,我们的脚步永不停息,少年热血和梦想华章,才刚刚开始。在她指尖的彩球上,炽热的青春有迹可循。“运动会的开幕仪......
  • 闲话 10.2
    你说的对,以前假期比上不足比下有余,现在没有下了。10.1上午的唐氏模拟赛,忙活一上午只有55pts,还因为T4freopen开错了挂15pts。T1感觉哪里很对但很怪,死活调不出来大样例三,于是两个小时就摆了,结果大败而归,事实上将我初版代码改一个地方就是正解,纯属南辕北辙还没走到头。看......
  • 闲话即时通讯:腾讯的成长史本质就是一部QQ成长史
    1、前言在猴年新春的时候,腾讯当时推出了新春广告片(点击观看视频),作为《弹指间心无间》的延续。片中通过春节期间发送QQ红包让家人打车回家团聚,让我们感受到了“最温暖的红包,给最爱的人”那种弹指间的感动。而就在这弹指一挥间,此次腾讯新春广告片距离2011年腾讯发布《弹指间心无......
  • 2024-09-28 闲话
    做大模型一年半,经历了无数场面试。经验我最常听到的候选人(尤其是学生)的说辞是:我没有大模型经验,可以给个机会吗?答案是,我们并不看重候选人的大模型训练经验。这里不是说经验不重要,而是大部分人的经验没有意义。只有头部大模型公司的核心骨干的经验才有意义,而这和绝大多数人选无关(e.......
  • 110.109 Introductory Financial Accounting
    110.109Introductory FinancialAccountingAssessment3 BookletDistanceandInternalSemester2– 2024IMPORTANT INFORMATIONThis is an electronic assessment and must be completed in the “Assessment 3 Answer Workbook” – Excel temp......
  • 【闲话】假如我们都是猫娘
    猫娘驯化实录ZHESHIWOYAOMOZHENGBEIDISANJIEMOZHENGXIANHUADASAIDECANSAIZUOPIN.(A:Chat-GPT4.0)(另:因为某些纯魔怔原因,我们连皮下内容也回了)。A17:33:41喵~主人你好呀!我是您的猫娘助手,挪威森林猫品种,身高148cm,梳着双马尾~需要我帮忙做点什么吗?(?ω??)Kiichi17:33:55主人大人,......
  • 闲话 24.9.11
    闲话哈哈,没有选题了。没有选题就不写了(最近摆的很舒服啊。等卖了题再拿题解充当闲话吧。碰壁:处理▂▕▄▄制▒▟▀问题不可以▙依赖[错误:所引对象未导引至对象实例;标准处理方法_004.rtf不存在]。不确定[已编辑]难的。推歌:樱桃簪子by天使盐feat.诗岸轻舟慢慢多......