poj 3648 Wedding 2sat

2sat

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=30*2+9;
int n,m;
int head[maxn];
int lon;
int dfn[maxn],low[maxn],stack[maxn],instack[maxn],s[maxn],un[maxn];
int count,top,con;
int head2[maxn],in[maxn],to[maxn],totop;
int col[maxn];
struct
{
    int next,to;
}e[100000];
void edgemake(int from,int to,int head[])
{
    e[++lon].to=to;
    e[lon].next=head[from];
    head[from]=lon;
}
void edgeini()
{
    memset(head,-1,sizeof(head));
    lon=-1;
}

void tarjan(int t)
{
    dfn[t]=low[t]=++count;
    instack[t]=1;
    stack[++top]=t;
    for(int k=head[t];k!=-1;k=e[k].next)
    {
        int u=e[k].to;
        if(dfn[u]==-1)
        {
            tarjan(u);
            low[t]=min(low[t],low[u]);
        }
        else if(instack[u])
        low[t]=min(low[t],dfn[u]);
    }
    if(dfn[t]==low[t])
    {
        ++con;
        while(1)
        {
            int u=stack[top--];
            instack[u]=0;
            s[u]=con;
            edgemake(con,u,un);
            if(u==t) break;
        }
    }
}

void tarjan()
{
    memset(dfn,-1,sizeof(dfn));
    memset(instack,0,sizeof(instack));
    memset(un,-1,sizeof(un));
    count=top=con=0;
    for(int i=0;i<n+n;i++)
    if(dfn[i]==-1)
    tarjan(i);
}

bool check()
{

    for(int i=0;i<n+n;i++)
    if(s[i]==s[i^1])
    return false;
    return true;
}

void makegraph()
{
    memset(head2,-1,sizeof(head2));
    for(int i=0;i<n+n;i++)
    for(int k=head[i];k!=-1;k=e[k].next)
    if(s[i]!=s[e[k].to])
    edgemake(s[e[k].to],s[i],head2);
}

void topo()
{
    memset(in,0,sizeof(in));
    top=totop=0;
    for(int i=1;i<=con;i++)
    for(int k=head[i];k!=-1;k=e[k].next)
    in[e[k].to]++;
    for(int i=1;i<=con;i++)
    if(in[i]==0)
    stack[++top]=i;

    while(top)
    {
        int u=stack[top--];
        to[++totop]=u;
        for(int k=head2[u];k!=-1;k=e[k].next)
        {
            int v=e[k].to;
            in[v]--;
            if(in[v]==0)
            {
                stack[++top]=v;
            }
        }
    }
}

void paint(int t)
{
    for(int k=head2[t];k!=-1;k=e[k].next)
    {
        int u=e[k].to;
        if(col[u]==-1)
        {
            col[u]=0;
            paint(u);
        }
    }
}

void colour()
{
    memset(col,-1,sizeof(col));
    for(int i=1;i<=con;i++)
    if(col[i]==-1)
    {
        col[i]=1;
        for(int k=un[i];k!=-1;k=e[k].next)
        {
            int u=e[k].to;
            if(col[s[u^1]]==-1)
            {
                col[s[u^1]]=0;
                paint(s[u^1]);
            }
        }
    }

}

int main()
{
    while(scanf("%d %d",&n,&m),n&&m)
    {
        edgeini();
        for(int i=1,from,to;i<=m;i++)
        {
            char txt,tmp;
            scanf("%d %c %d %c",&from,&tmp,&to,&txt);
            from*=2;
            to*=2;
            if(tmp=='w') from++;
            if(txt=='w') to++;
            edgemake(from,to^1,head);
            edgemake(to,from^1,head);
        }
        edgemake(1,0,head);
        edgemake(0,0,head);
        tarjan();
        if(!check())
        {
            printf("bad luck\n");
            continue;
        }
        makegraph();
        topo();
        colour();
        for(int i=2;i<n+n-2;i+=2)
        if(col[s[i]]==0)
        {
            printf("%dh ",i/2);
        }
        else
        printf("%dw ",i/2);
        if(col[s[n+n-2]]==0)
        printf("%dh ",(n+n-2)/2);
        else
        printf("%dw ",(n+n-2)/2);
        printf("\n");
    }
    return 0;
}

【SCI复现】基于纳什博弈的多微网主体电热双层共享策略研究(Matlab代码实现)内容概要:本文围绕“基于纳什博弈的多微网主体电热双层共享策略研究”展开,结合Matlab代码实现,复现了SCI级别的科研成果。研究聚焦于多个微网主体之间的能源共享问题,引入纳什博弈理论构建双层优化模型,上层为各微网间的非合作博弈策略,下层为各微网内部电热联合优化调度,实现能源高效利用与经济性目标的平衡。文中详细阐述了模型构建、博弈均衡求解、约束处理及算法实现过程,并通过Matlab编程进行仿真验证,展示了多微网在电热耦合条件下的运行特性和共享效益。; 适合人群:具备一定电力系统、优化理论和博弈论基础知识的研究生、科研人员及从事能源互联网、微电网优化等相关领域的工程师。; 使用场景及目标:① 学习如何将纳什博弈应用于多主体能源系统优化;② 掌握双层优化模型的建模与求解方法;③ 复现SCI论文中的仿真案例,提升科研实践能力;④ 为微电网集群协同调度、能源共享机制设计提供技术参考。; 阅读建议:建议读者结合Matlab代码逐行理解模型实现细节,重点关注博弈均衡的求解过程与双层结构的迭代逻辑,同时可尝试修改参数或扩展模型以适应不同应用场景,深化对多主体协同优化机制的理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值