Uvalive 6264 Conservation 拓扑排序

本文探讨了拓扑排序在解决实验室任务调度问题的应用,通过两次拓扑排序计算从不同实验室开始所需的最少转移次数,以完成所有实验任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:有两个实验室,有n个实验和m对实验依赖 (a,b) 代表实验 b 必须在实验a之后才能进行,一开始可以在任意两个实验室进行实验,问最少要转移多少次实验室可以把这n个实验全部完成。
两次拓扑排序分别计算从1号实验室开始和从2号实验室开始所需要转移的次数就可以。。。
代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 100000+1;
int n,m,T;
struct Edge {
    int to,next;
    Edge(){}
    Edge(int _to,int _next):to(_to),next(_next){}
}e[1000000+5];
int head[100000+1],tot;
void init(){
for(int i=1;i<=n;i++)head[i]=-1;
//  memset(head,-1,sizeof(head));
    tot=0;
}
void AddEdge(int u,int v){
    e[tot]=Edge(v,head[u]);
    head[u]=tot++;
}
void Read(int &x){
    char ch;
    while((ch=getchar())&&!isdigit(ch));
    x=0;
    do {
        x=(x<<1)+(x<<3)+(ch^48);
    }while((ch=getchar())&&isdigit(ch));
}
int que1[MAXN*2],que2[MAXN*2];
int front1,rear1,front2,rear2;
int du[MAXN],type[MAXN],du1[MAXN];

int countt(){
    front1=rear1=front2=rear2=0;
    //memcpy(du1,du,sizeof(du));
    for(int i=1;i<=n;i++){
        du1[i]=du[i];
        if(du[i]==0){
            if(type[i]==1) que1[rear1++]=i;
            if(type[i]==2) que2[rear2++]=i;
            --du[i];
        }
    }
    int cnt=0;
    int pre=1;
    //if(rear1==0)pre=2;
    //else pre=1;
    while((front1!=rear1)||(front2!=rear2)){
        int tf=0;
        while(front1!=rear1){
            tf=1;
            int u=que1[front1++];
            for(int i=head[u];i!=-1;i=e[i].next){
                int v=e[i].to;
                du[v]--;
                if(du[v]==0){
                    if(type[v]==1)que1[rear1++]=v;//q1.push(v);
                    if(type[v]==2)que2[rear2++]=v;//q2.push(v);
                    du[v]--;
                }
            }
        }
        if(tf&&pre!=1){
            pre=1;++cnt;
        }
        tf=0;
        while(front2!=rear2){
            tf=1;
            int u=que2[front2++];
            for(int i=head[u];i!=-1;i=e[i].next){
                int v=e[i].to;
                du[v]--;
                if(du[v]==0){
                    if(type[v]==1)que1[rear1++]=v;//q1.push(v);
                    if(type[v]==2)que2[rear2++]=v;//q2.push(v);
                    du[v]--;
                }
            }
        }
        if(tf&&pre!=2){
            pre=2;++cnt;
        }
    }

 //   memcpy(du,du1,sizeof(du));
    front1=rear1=front2=rear2=0;
    for(int i=1;i<=n;i++){
        du[i]=du1[i];
        if(du[i]==0){
            if(type[i]==1)que1[rear1++]=i;//q1.push(i);
            if(type[i]==2)que2[rear2++]=i;//q2.push(i);
            --du[i];
        }
    }
    int cnt1=0;
    pre=2;
    while((front1!=rear1)||(front2!=rear2)){
        int tf=0;
        while(front2!=rear2){
            tf=1;
            int u=que2[front2++];
            for(int i=head[u];i!=-1;i=e[i].next){
                int v=e[i].to;
                du[v]--;
                if(du[v]==0){
                    if(type[v]==1)que1[rear1++]=v;//q1.push(v);
                    if(type[v]==2)que2[rear2++]=v;//q2.push(v);
                    du[v]--;
                }
            }
        }
        if(tf&&pre!=2){
            pre=2;++cnt1;
        }
        tf=0;
        while(front1!=rear1){
            tf=1;
            int u=que1[front1++];
            for(int i=head[u];i!=-1;i=e[i].next){
                int v=e[i].to;
                du[v]--;
                if(du[v]==0){
                    if(type[v]==1)que1[rear1++]=v;//q1.push(v);
                    if(type[v]==2)que2[rear2++]=v;//q2.push(v);
                    du[v]--;
                }
            }
        }
        if(tf&&pre!=1){
            pre=1;++cnt1;
        }
    }
    return cnt<cnt1?cnt:cnt1;

    //return cnt;
}
int main()
{
    //while(~scanf("%d",&T))
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        init();memset(du,0,sizeof(du));
        for(int i=1;i<=n;i++) Read(type[i]);//scanf("%d",&type[i]);
        for(int i=0,x,y;i<m;i++){
           // scanf("%d%d",&x,&y);
            Read(x),Read(y);
            AddEdge(x,y);

            ++du[y];
        }
        printf("%d\n",countt());
    }
    return 0;
}
内容概要:本文详细介绍了基于FPGA的144输出通道可切换电压源系统的设计与实现,涵盖系统总体架构、FPGA硬件设计、上位机软件设计以及系统集成方案。系统由上位机控制软件(PC端)、FPGA控制核心和高压输出模块(144通道)三部分组成。FPGA硬件设计部分详细描述了Verilog代码实现,包括PWM生成模块、UART通信模块和温度监控模块。硬件设计说明中提及了FPGA选型、PWM生成方式、通信接口、高压输出模块和保护电路的设计要点。上位机软件采用Python编写,实现了设备连接、命令发送、序列控制等功能,并提供了一个图形用户界面(GUI)用于方便的操作和配置。 适合人群:具备一定硬件设计和编程基础的电子工程师、FPGA开发者及科研人员。 使用场景及目标:①适用于需要精确控制多通道电压输出的实验环境或工业应用场景;②帮助用户理解和掌握FPGA在复杂控制系统中的应用,包括PWM控制、UART通信及多通道信号处理;③为研究人员提供一个可扩展的平台,用于测试和验证不同的电压源控制算法和策略。 阅读建议:由于涉及硬件和软件两方面的内容,建议读者先熟悉FPGA基础知识和Verilog语言,同时具备一定的Python编程经验。在阅读过程中,应结合硬件电路图和代码注释,逐步理解系统的各个组成部分及其相互关系。此外,实际动手搭建和调试该系统将有助于加深对整个设计的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值