Codeforces Round #503 (by SIS, Div. 1) C. Sergey's problem

版权声明:本文为博主原创文章,爱转载的表明出处就好. https://blog.csdn.net/qq_36797743/article/details/81611312

题意

自己看

题解

感觉这个构造并不是很会想。。
考虑,我们随便枚举一个点 x
然后,我们把他可以直接到达的点全部删掉
剩下一个图
如果我们可以得到这个图的合法方案
然后看一下,如果剩下的图中,有一个有色点可以到达 x ,那么 x 和他所连向的点不染色即可
否则,我们把 x 染色肯定是合法的
于是得到一个做法
从1到n扫过去,如果这个点还在,就把他删掉,模拟上述过程
然后把删掉的点倒着做回来更新图即可

CODE:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<stack>
using namespace std;
const int N=1000005;
int n,m;
struct qq
{
    int x,y,last;
}e[N];int num,last[N];
void init (int x,int y)
{
    num++;
    e[num].x=x;e[num].y=y;
    e[num].last=last[x];
    last[x]=num;
}
bool del[N];
bool ok[N];
stack<int> sta;
int ans[N];
int main()
{
    memset(ok,true,sizeof(ok));
    memset(del,false,sizeof(del));
    num=0;memset(last,-1,sizeof(last));
    scanf("%d%d",&n,&m);
    for (int u=1;u<=m;u++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        init(x,y);
    }
    for (int u=1;u<=n;u++)
        if (del[u]==false)
        {
            sta.push(u);
            //printf("%d\n",u);
            for (int i=last[u];i!=-1;i=e[i].last)
            {
                int y=e[i].y;
                del[y]=true;
            }
        }
    while (!sta.empty())
    {
        int x=sta.top();sta.pop();
        if (ok[x]==true)
        {
            //printf("x:%d %d\n",x,ok[x]);
            for (int u=last[x];u!=-1;u=e[u].last)
            {
                int y=e[u].y;
                ok[y]=false;
                //printf("y:%d %d\n",y,ok[y]);
            }
            ans[++ans[0]]=x;
        }
    }
    printf("%d\n",ans[0]);
    for (int u=1;u<=ans[0];u++)
        printf("%d ",ans[u]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36797743/article/details/81611312
今日推荐