POJ 3648 Wedding

2-SAT

关于了解2-SAT,推荐两个地方:《由对称性解2-SAT问题》、【研究总结】2-sat问题

每次找到一个未被确定的Si,使得不存在Si Si’,选择Si及其后代节点而删除Si’及Si‘的前代节点。一定可以构造出一组可行解。

一个重要的性质是不管怎么加限制,对于任意一对Si, Si’ , Si的后代节点与Si’ 的前代节点相互对称总成立。

一类奇怪的加边是形如Si->Si’的,这条边保证了逆拓扑序时先访问到Si’,所以不会产生矛盾,图形依然对称。同时由这条边引起的环也是对称的,所以没有问题。

主要就是利用了2-SAT模型的对称性,搞出了 O(n+m) 时间复杂度的算法。

这题非常坑,输入数据里有形如1w2h这样中间没空格的,读入”%s%s”就挂了,坑了好久….好气啊好气啊

还有网上的代码为什么动不动就是一百多行啊...

#include<cstdio> 
#include<queue>
#include<cstring>
#define N 200005
#define cmin(u,v) ((u)>(v)?(u)=(v):0)
using namespace std;
namespace runzhe2000
{
    // 2*i wife 2*i+1 husb
    char str[5];
    int n, m, ecnt, pecnt, last[N], dfn[N], low[N], timer, sta[N], insta[N], stacnt, bel[N], bcnt, deg[N], col[N], conf[N];
    struct edge{int next, to;}e[N<<1];
    struct pdge{int a, b;}pe[N<<1];
    void addedge(int a, int b)
    {
        pe[++pecnt] = (pdge){a, b};
        e[++ecnt] = (edge){last[a], b};
        last[a] = ecnt;
    }
    void tarjan(int x)
    {
        dfn[x] = low[x] = ++timer; insta[x] = 1; sta[++stacnt] = x;
        for(int i = last[x]; i; i = e[i].next)
        {
            int y = e[i].to;
            if(!dfn[y]) tarjan(y), cmin(low[x], low[y]);
            else if(insta[y]) cmin(low[x], dfn[y]);
        }
        if(low[x] == dfn[x])
        {
            int y; ++bcnt;
            do {bel[y = sta[stacnt--]] = bcnt; insta[y] = 0;}
            while(y != x);
        }
    }
    void clr()
    {
        timer = ecnt = pecnt = 0;
        memset(col,0,sizeof(col)); memset(last,0,sizeof(last)); 
        memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); 
    }
    void main()
    {
        for(; scanf("%d%d",&n,&m) && (n || m); )
        {
            clr(); addedge(1, 0); n--;
            for(int i = 1, x, y; i <= m; i++)
            {
                scanf("%d%c%d%c",&x,&str[0],&y,&str[1]);
                (x<<=1) |= (str[0] == 'h' ? 1 : 0);
                (y<<=1) |= (str[1] == 'h' ? 1 : 0);
                addedge(x^1, y); addedge(y^1, x);
            }
            for(int i = 0; i <= (n<<1|1); i++) if(!dfn[i]) tarjan(i);
            int ok = 1; for(int i = 0; i <= n; i++) 
                if(bel[i<<1] == bel[i<<1|1]){puts("bad luck"); {ok=0; break;}} 
                else conf[bel[i<<1]] = bel[i<<1|1], conf[bel[i<<1|1]] = bel[i<<1];
            if(!ok) continue;
            memset(last,0,sizeof(last)); ecnt = 0;
            for(int i = 1, ii = pecnt; i <= ii; i++)if(bel[pe[i].a] != bel[pe[i].b]) addedge(bel[pe[i].b], bel[pe[i].a]), ++deg[bel[pe[i].a]];
            queue<int> q; for(int i = 1; i <= bcnt; i++) if(!deg[i]) q.push(i);
            for(; !q.empty(); )
            {
                int x = q.front(); q.pop();
                if(!col[x]) col[x] = 1, col[conf[x]] = -1;
                for(int i = last[x]; i; i = e[i].next)
                {
                    int y = e[i].to;
                    if(!--deg[y])q.push(y);
                }
            }
            for(int sc = col[bel[0]], i = 2; i <= (n<<1|1); i++) if(sc == col[bel[i]]) printf("%d%c ",i>>1,(i&1)?'h':'w');  puts("");
        }
    }
}
int main()
{
    runzhe2000::main();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值