LightOJ 1300 - Odd Personality

来源:互联网 发布:办公室做数据是做什么 编辑:程序博客网 时间:2024/05/21 22:52

题意:

有多少个点可以走n次之后回到该点 ,n为奇数,

这里不是所有点都联通的,

#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <stack>#include <algorithm>#include <cmath>#include <map>using namespace std;const int N = 10009;const int M = 40009;struct LT{    int nex,to;} L[M];int F[N],cnt=0;void add(int f,int t){    L[cnt].nex = F[f];    L[cnt].to = t;    F[f] = cnt++;}int n,m;void init(){    int a,b;    scanf("%d%d",&n,&m);    memset(F,0,sizeof(F));cnt=1;    for(int i=0;i<m;i++)    {        scanf("%d%d",&a,&b);        add(a,b);add(b,a);    }}int dfn[N],low[N],post[N],ind,color,col[N];stack<int>S;void tarjan(int k,int fa){    //cout<<k<<endl;    dfn[k]=low[k] = ind++;    S.push(k);post[k] = 1;    for(int i=F[k];i;i=L[i].nex)    {        int to = L[i].to;        if(to==fa) continue;        if(!dfn[to])        {            tarjan(to,k);            low[k] = min(low[k],low[to]);        }        else if(post[to]&&dfn[to]<low[k])            low[k] = dfn[to];    }    if(low[k]==dfn[k])    {        int i;color++;        for(i=S.top(),S.pop();i!=k;i=S.top(),S.pop())        {            col[i] = color;            post[i] = 0;        }        post[k] = 0,col[k] = color;    }}int dp[N][2];int v[N];struct nod{    int to,c;};queue<nod>que;void op(int k){   // cout<<k<<endl;    int co = col[k];    nod e,t;    while(!que.empty()) que.pop();    e.c =0,e.to = k;    que.push(e);    dp[k][0] =1;    v[k] = 1;   // cout<<"KKKKK"<<endl;    while(!que.empty())    {     //   cout<<"LLL"<<endl;        e = que.front() ;que.pop();       // cout<<"  "<<e.to<<endl;        int p = e.c^1;        for(int i=F[e.to];i;i=L[i].nex)        {            int to = L[i].to;            if(col[to]!=co) continue;            v[to] = 1;            if(dp[to][p]==0)            {                dp[to][p]=1;                t.to = to,t.c = p;                que.push(t);            }        }    }}void solve(){    memset(dfn,0,sizeof(dfn));ind = 1;color = 0;    for(int i=0;i<n;i++)    if(!dfn[i])    tarjan(i,-1);    memset(dp,0,sizeof(dp));    memset(v,0,sizeof(v));    int ans = 0;    for(int i=0;i<n;i++)    if(!v[i])    {        op(i);    }    for(int i=0;i<n;i++)    if(dp[i][0]&&dp[i][1]) ans++;    printf("%d\n",ans);}int main(){    freopen("in.txt","r",stdin);    int cas,T=1;    scanf("%d",&cas);    while(cas--)    {        init();        printf("Case %d: ",T++);        solve();    }    return 0;}


原创粉丝点击