【topsort】Day 7 提高组模拟B组 T1 挑竹签

题目大意

给定一些竹签它们有的压着别的竹签,有的被别的竹签压,在保证竹签塔不会坍塌的情况下,求出最多可以去除的竹签数

解题思路

思路1:
因为 x -> y ,那么 x 就取出后就可以取出 y ,这样就满足拓扑序,若 x , y 之间互相约束彼此,那么它们就不会在拓扑序中,也就是不被选择,所以我们只需要跑一遍 t o p s o r t 计算入队次数就可以了
思路2
x -> y ,这是单向传递,当且仅当两根竹签互相约束时不能求出,即为一个强连通分量,所以我们也可以用 T a r j a n 缩点求解
但是由于本人太弱不会打Tarjan就不放代码啦哈哈哈

代码

#include<queue>
#include<cstdio>
#include<cstring>
#define M 1000001
using namespace std;int ans,tot,l[M],d[M],m,x,y,n;
queue<int>q;
struct node{int next,to;}e[M];
void add(int u,int v){e[tot]=(node){l[u],v};l[u]=tot++;return;}
int main()
{
    freopen("mikado.in","r",stdin);
    freopen("mikado.out","w",stdout);
    memset(l,-1,sizeof(l));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) scanf("%d%d",&x,&y),add(x,y),d[y]++;
    for(int i=1;i<=n;i++) if(!d[i]) q.push(i),ans++;//求出入度
    while(q.size())
    {
        x=q.front();q.pop();
        for(int i=l[x];~i;i=e[i].next) if(!(--d[e[i].to])) q.push(e[i].to),ans++;//计算入队次数
    }
    printf("%d",ans);//输出
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/81021882
今日推荐