Uvalive 6264 Conservation 拓扑排序

来源:互联网 发布:会声会影x6软件 编辑:程序博客网 时间:2024/06/06 01:12

题意:有两个实验室,有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;}
0 0