poj 2762 Tarjan+拓扑排序 入度为1的集合的个数

来源:互联网 发布:matlab解最优化问题 编辑:程序博客网 时间:2024/05/07 20:54

题意:满足任取两点x,y,x可以到y,或者y能到x.

解法:缩点,拓扑排序时,如果同时有两个入度为0的点,就输出“NO”。

/*----------------------------------   Love is more than a word.   It says so much.   When I see these four letters,   I almost feel your touch.   This is only happened since   I fell in love with you.   Why this word does this,   I haven't got a clue.                   To My Goddess                          CY----------------------------------*/#include<iostream>#include<cstring>#include<algorithm>#include<cstdlib>#include<vector>#include<cmath>#include<stdlib.h>#include<iomanip>#include<list>#include<deque>#include<map>#include <stdio.h>#include <queue>#define maxn 50000+5#define ull unsigned long long #define ll long long#define reP(i,n) for(i=1;i<=n;i++) #define REP(i,a,b) for(i=a;i<=b;i++)  #define rep(i,n) for(i=0;i<n;i++)#define cle(a) memset(a,0,sizeof(a)) #define clehead(a) rep(i,maxn)a[i]=-1/*  The time of story :  **  while(1)    {         once upon a time,         there was a mountain,         on top of which there was a temple,         in which there was an old monk and a little monk.         Old monk was telling stories inside the temple.         What was he talking about?  **  }   ÎûÎû   (*^__^*)*/#define sci(a) scanf("%d",&a) #define scd(a) scanf("%lf",&a)  #define pri(a) printf("%d",a)   #define prie(a) printf("%d\n",a)    #define prd(a)  printf("%lf",a)     #define prde(a) printf("%lf\n",a)      #define pre printf("\n")#define LL(x) x<<1 #define RR(x) x<<|1#define pb push_back#define mod 90001#define PI 3.141592657const ull INF = 1LL << 61;const int inf =   int(1e5)+10;const double eps=1e-5;using namespace std;struct node{    int be;   int to,w;   int next;}edge[maxn*10];node e[maxn*10];bool cmp(int a,int b){    return a>b;}int head[maxn];int m;int low[maxn],dfn[maxn],stack[maxn],used[maxn];int cnt=0;int in[maxn],out[maxn];void add(int x,int y){    edge[cnt].be=x;    edge[cnt].to=y;    edge[cnt++].next=head[x];    head[x]=(cnt-1);}void add1(int x,int y){    e[cnt].be=x;    e[cnt].to=y;    e[cnt].next=head[x];    head[x]=cnt++;}void init(){    memset(head,-1,sizeof(head));    cle(used),cle(low),cle(dfn),cle(in),cle(out);    m=0;    cnt=0;}int tarbfs(int k,int lay,int &scc_num){    used[k]=1;    low[k]=lay;    dfn[k]=lay;    stack[++m]=k;    for(int i=head[k];i!=-1;i=edge[i].next)    {        if(used[edge[i].to]==0)        {            tarbfs(edge[i].to,++lay,scc_num);        }        if(used[edge[i].to]==1)        {            low[k]=min(low[k],low[edge[i].to]);        }    }    if(dfn[k]==low[k])    {        ++scc_num;        do{            low[stack[m]]=scc_num;            used[stack[m]]=2;        }while(stack[m--]!=k);    }    return 0;}int doit(int n){    int i,j,k;    int iq=0;    int ans=0;    for(i=1;i<=n;i++)    {        if(in[i]==0)        {            j=i;            ans++;        }    }    if(ans>1)return 0;    ans=0;    int num=n;    int u;    while(num--)    {        ans=0;        for(i=head[j];i!=-1;i=e[i].next)        {            u=e[i].to;            in[u]--;            if(in[u]==0)            {                ans++;                j=u;            }        }        if(ans>1)return 0;    }    return 1;}int main(){    freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int T;    cin>>T;    while(T--)    {        init();        int n,k;        cin>>n>>k;        int i,j;        int scc_num=0;        int lay=0;        for(i=1;i<=k;i++)        {            int x,y;            scanf("%d%d",&x,&y);            add(x,y);        }        for(i=1;i<=n;i++)        {            if(used[i]==0)            {                tarbfs(i,lay,scc_num);            }        }        int len=cnt;        cle(in),cle(out);        memset(head,-1,sizeof(head));        cnt=0;        for(i=0;i<len;i++)        {            if(low[edge[i].be]!=low[edge[i].to])            {                add1(low[edge[i].be],low[edge[i].to]);                in[low[edge[i].to]]++;            }        }        //cout<<cnt<<endl;        if(doit(scc_num)==1)        {            cout<<"Yes"<<endl;        }        else cout<<"No"<<endl;    }    return 0;}


0 0