【CodeForces - 770C】Online Courses In BSU(拓扑排序)

Now you can take online courses in the Berland State University! Polycarp needs to pass k main online courses of his specialty to get a diploma. In total n courses are availiable for the passage.

The situation is complicated by the dependence of online courses, for each course there is a list of those that must be passed before starting this online course (the list can be empty, it means that there is no limitation).

Help Polycarp to pass the least number of courses in total to get the specialty (it means to pass all main and necessary courses). Write a program which prints the order of courses.

Polycarp passes courses consistently, he starts the next course when he finishes the previous one. Each course can’t be passed more than once.

Input
The first line contains n and k ( 1   ≤   k   ≤   n   ≤   1 0 5 ) (1 ≤ k ≤ n ≤ 10^5) (1kn105) — the number of online-courses and the number of main courses of Polycarp’s specialty.

The second line contains k distinct integers from 1 to n — numbers of main online-courses of Polycarp’s specialty.

Then n lines follow, each of them describes the next course: the i-th of them corresponds to the course i. Each line starts from the integer ti (0 ≤ ti ≤ n - 1) — the number of courses on which the i-th depends. Then there follows the sequence of ti distinct integers from 1 to n — numbers of courses in random order, on which the i-th depends. It is guaranteed that no course can depend on itself.

It is guaranteed that the sum of all values ti doesn’t exceed 1 0 5 10^5 105.

Output
Print -1, if there is no the way to get a specialty.

Otherwise, in the first line print the integer m — the minimum number of online-courses which it is necessary to pass to get a specialty. In the second line print m distinct integers — numbers of courses which it is necessary to pass in the chronological order of their passage. If there are several answers it is allowed to print any of them.

Examples
Input
6 2
5 3
0
0
0
2 2 1
1 4
1 5
Output
5
1 2 3 4 5
Input
9 3
3 9 5
0
0
3 9 4 5
0
0
1 8
1 6
1 2
2 1 2
Output
6
1 2 9 4 5 3
Input
3 3
1 2 3
1 2
1 3
1 1
Output
-1
ac代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
#define maxn 100005
#define ll long long
#define mod 1000000007
#define INF 0x7fffffff
using namespace std;
int head[maxn],_next[maxn],to[maxn],edge;
void addEdge(int x,int y);
int vis[maxn];
int a[maxn];
int ans[maxn],cnt;
int n,k;
bool dfs(int u);
int main()
{
    cin>>n>>k;
    for(int i=1;i<=k;i++)scanf("%d",a+i);
    int x,y;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        while(x--)
        {
            scanf("%d",&y);
            addEdge(i,y);
        }
    }
    bool sign=true;
    for(int i=1;i<=k;i++)
    {
        if(!vis[a[i]]&&!dfs(a[i]))
        {
            sign=false;
            break;
        }
    }
    if(sign)
    {
        printf("%d\n",cnt);
        for(int i=1;i<cnt;i++)printf("%d ",ans[i]);
        printf("%d\n",ans[cnt]);
    }
    else printf("-1\n");
    return 0;
}
void addEdge(int x,int y)
{
    to[++edge]=y;_next[edge]=head[x];head[x]=edge;
}
bool dfs(int u)
{
    vis[u]=-1;
    for(int i=head[u];i;i=_next[i])
    {
        int v=to[i];
        if(vis[v]==-1)return false;
        else if(!vis[v]&&!dfs(v))return false;
    }
    vis[u]=1;
    ans[++cnt]=u;
    return true;
}

不知道为啥bfs写法会wa啊。。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<set>
#define maxn 100005
#define ll long long
#define mod 1000000007
#define INF 0x7fffffff
using namespace std;
int head[maxn],_next[maxn],to[maxn],edge;
void addEdge(int x,int y)
{
    to[++edge]=y;_next[edge]=head[x];head[x]=edge;
}
int a[maxn];
int ans[maxn],cnt;
int inD[maxn];
bool must[maxn];
int n,k;
int main()
{
    cin>>n>>k;
    for(int i=1;i<=k;i++)
    {
        scanf("%d",a+i);
        must[a[i]]=true;
    }
    int x,y;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        while(x--)
        {
            scanf("%d",&y);
            inD[y]++;
            addEdge(i,y);
        }
    }
    queue<int>que;
    for(int i=1;i<=n;i++)
        if(!inD[i])que.push(i);
    int tot=0;
    while(que.size())
    {
        int u=que.front();que.pop();
        tot++;
        if(must[u])ans[++cnt]=u;
        for(int i=head[u];i;i=_next[i])
        {
            int v=to[i];
            if(must[u])must[v]=true;
            inD[v]--;
            if(!inD[v])
                que.push(v);

        }
    }
    if(tot==n)
    {
        printf("%d\n",cnt);
        for(int i=cnt;i>1;i--)printf("%d ",ans[i]);
        printf("%d\n",ans[1]);
    }
    else printf("-1\n");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值