Fork me on GitHub

UVALive 6264 Conservation --拓扑排序

题意:一个展览有n个步骤,告诉你每一步在那个场馆举行,总共2个场馆,跨越场馆需要1单位时间,先给你一些约束关系,比如步骤a要在b前执行,问最少的转移时间是多少。

解法:根据这些约束关系可以建立有向边,可以看出是拓扑排序问题,问题是怎样拓扑排序。

进行两次拓扑排序,分别建立两个集合,一个放场馆1举行的步骤,一个放场馆2的,然后第一次从场馆1开始进行拓扑排序,每次一个场馆取完后看另一个场馆是否有步骤要执行,有则执行,然后将度数变为0的压入队列,如此往复。第二次从场馆2开始进行。得出的最小值为答案。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define N 100007

int in[N],co[N],tin[N];
vector<int> G[N];

int min(int ka,int kb)
{
    if(ka < kb)
        return ka;
    return kb;
}

int main()
{
    int t,n,m,i,j,u,v;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&co[i]);
            G[i].clear();
        }
        memset(in,0,sizeof(in));
        while(m--)
        {
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
            in[v]++;
        }
        for(i=1;i<=n;i++)
            tin[i] = in[i];
        int sum = 0;
        queue<int> que[2];
        int tot = 2;
        int ans = Mod;
        while(tot--)
        {
            int cnt = 0;
            int now = tot;
            for(i=1;i<=n;i++)
                in[i] = tin[i];
            for(i=1;i<=n;i++)
            {

                if(in[i] == 0)
                {
                    if(co[i] == 1)
                        que[0].push(i);
                    else
                        que[1].push(i);
                }
            }
            do
            {
                cnt++;
                while(!que[now].empty())
                {
                    int u = que[now].front();
                    que[now].pop();
                    for(i=0;i<G[u].size();i++)
                    {
                        int v = G[u][i];
                        in[v]--;
                        if(in[v] == 0)
                        {
                            if(co[v] == 1)
                                que[0].push(v);
                            else
                                que[1].push(v);
                        }
                    }
                }
                now = 1-now;
            }while(!que[now].empty());
            //cout<<"cnt = "<<cnt<<endl;
            ans = min(ans,cnt);
        }
        printf("%d\n",ans-1);
    }
    return 0;
}
View Code

 

posted @ 2014-07-29 21:15  whatbeg  阅读(248)  评论(0编辑  收藏  举报