法一:
过程:一开始我直接拿bfs跑,没有用去重,导致一个节点重复算了多次,使用了bitset的位运算|去重后,答案才对,bitset大法好(bitset还省空间);bitset数组类似与bool数组,但是省空间
思路:前向星建图,将所有的visit[u][u]初始化为1(自己和自己相连),如果一个点u只和本身相连就dfs一下,遍历所有与u相连的点v,visit[u]=visit[u]|visit[v] ,并一下则所有使visit[t][i]=1成立的i都能使visit[u][i]=1(因为u和v相连,所以所有和v相连的点都和u相连)到出度为0的节点(即head[u]==0)返回;
#include <iostream>
#include <queue>
#include <bitset>
#include <cstdio>
using namespace std;
struct node
{
int next,to;
}e[30005];
int head[30005]={0};
int cnt=1;
bitset<30005>visit[30005];///开一个大小为30005的字节数组,数组中每个元素的长度为30005(每一位为0或1)
void add(int u,int v)
{
e[cnt]={head[u],v};
head[u]=cnt++;
}
inline void ini(int n)
{
for(int i=1;i<=n;i++) visit[i][i]=1;
}
void dfs(int u)
{
if(head[u]==0) {visit[u][u]=1; return;}
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(visit[v].count()==1)dfs(v);
visit[u]|=visit[v];
}
}
int main()
{
int n;int m;
cin>>n>>m;
ini(n);
for(register int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
}
for(register int i=1;i<=n;i++)
{
if(visit[i].count()==1) dfs(i);
printf("%d\n",visit[i].count());///visit[i].count()计算visit[i]中有多少个1
}
return 0;
}
法二:
思路:拓扑排序一下,按逆序来遍历节点,先初始化visit[u][u]=1,将该节点u的visit[u]与所有与其相连的节点v visit[u]|=visit[v]即可
#include <iostream>
#include <queue>
#include <bitset>
#include <cstdio>
using namespace std;
struct node
{
int next,to;
}e[30005];
int head[30005]={0};
int top[30005];
int deg[30005];
int cnt=1,tot=1;
bitset<30005>visit[30005];
void add(int u,int v)
{
e[cnt]={head[u],v};
head[u]=cnt++;
deg[v]++;
}
void topsort(int n)
{
queue<int>q;
for(int i=1;i<=n;i++) if(!deg[i]) q.push(i);
while(!q.empty())
{
int u=q.front();
q.pop();
top[tot++]=u;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
deg[v]--;
if(!deg[v]) q.push(v);
}
}
}
int main()
{
int n;int m;
cin>>n>>m;
//ini(n);
for(register int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
}
topsort(n);
for(int i=tot-1;i>=1;i--)
{
int u=top[i];
visit[u][u]=1;
for(int j=head[u];j;j=e[j].next)
{
int v=e[j].to;
visit[u]|=s[v];
}
}
for(int i=1;i<=n;i++) printf("%d\n",visit[i].count());
return 0;
}
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int N=200;
char name1[50],name2[50];
char name[N+5][50];
struct node
{
int next,to;
}e[3005];
int head[3005]={0};
int top[3005];
int deg[3005];
int cnt=1,tot=1;
bitset<305>visit[305];
void add(int u,int v)
{
e[cnt]={head[u],v};
head[u]=cnt++;
deg[v]++;
}
inline void ini(int n)
{
for(int i=1;i<=n;i++) visit[i][i]=1;
}
void dfs(int u)
{
if(head[u]==0) {visit[u][u]=1; return;}
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
if(visit[v].count()==1)dfs(v);
visit[u]|=visit[v];
//cout<<"u"<<u<<'='<<visit[u].count()<<endl;
}
//cout<<endl;
}
int main()
{
int n,m,k=1;
scanf("%d %d",&n,&m);
//memset(a,0,sizeof(0));
for(int i=1;i<=n;i++)
{
scanf("%s are worse than %s",name1,name2);
if(k==0)
{
strcpy(name[k++],name1);
strcpy(name[k++],name2);
//a[1][2]=-1;
add(2,1);
}
else
{
int r,s,flag=0;
for(int i=1;i<k;i++)
{
if(strcmp(name1,name[i])==0)
{
r=i;
flag=1;
break;
}
}
if(flag==0)
{
r=k;
k++;
strcpy(name[r],name1);
}
flag=0;
for(int i=1;i<k;i++)
{
if(strcmp(name2,name[i])==0)
{
s=i;
flag=1;
break;
}
}
if(flag==0)
{
s=k;
k++;
strcpy(name[s],name2);
}
//a[r][s]=-1;
add(s,r);
}
}
ini(k);
for(int i=1;i<k;i++) if(visit[i].count()==1) dfs(i);
for(int i=1;i<=m;i++)
{
int r,s;int flag=0;
scanf("%s are worse than %s",name1,name2);
int j;
for(j=1;j<k;j++)
{
if(strcmp(name1,name[j])==0)
{
r=j;
break;
}
}
if(j==k) flag=1;
for(j=1;j<k;j++)
{
if(strcmp(name2,name[j])==0)
{
s=j;
break;
}
}
if(j==k) flag=1;
//cout<<"s="<<s<<" r="<<r<<endl;
if(flag==1){printf("Pants on Fire\n");continue;}
else
{
if(visit[s][r]==1) printf("Fact\n");
else if(visit[r][s]==1) printf("Alternative Fact\n");
else printf("Pants on Fire\n");
}
}
return 0;
}