0
点赞
收藏
分享

微信扫一扫

FFF at Valentine HDU - 6165

​​点击打开链接​​

如果u不能到达v v也不能到达u 那两个人就未必能找到彼此

数据量比较小 每个点都暴力搜索跑一边就可以 得到一个可达矩阵

但是学长教了我强连通分量的做法 速度快了差不多十倍

先通过tarjan来缩点 这样每一个强连通子图就可以看做一个点 用这些点再建新图 然后暴力搜索 看是否存在一条链

这样等于省去了在每个强连通分量里乱转的时间

 

Tarjan

 

#include <bits/stdc++.h>
using namespace std;

struct node
{
int v;
int next;
};

stack <int> stk;
node edge1[12010],edge2[12010];
int mat[1010][1010];
int first1[1010],first2[1010],book[1010],dfn[1010],low[1010],belong[1010];
int n,m,num,sum,cnt,flag;

void addedge(int u,int v,int* first,node* edge);
void tarjan();
void dfsI(int cur);
void calculate();
void dfsII(int cur,int f);

int main()
{
int t,i,u,v;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(first1,-1,sizeof(first1));
num=0;
for(i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v,first1,edge1);
}
tarjan();
calculate();
if(flag==1) printf("I love you my love and our love save us!\n");
else printf("Light my fire!\n");
}
return 0;
}

void addedge(int u,int v,int* first,node* edge)
{
edge[num].v=v;
edge[num].next=first[u];
first[u]=num++;
return;
}

void tarjan()
{
int i,u,v;
while(!stk.empty()) stk.pop();
memset(book,0,sizeof(book));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(belong,0,sizeof(belong));
sum=0,cnt=0;
for(i=1;i<=n;i++)
{
if(dfn[i]==0)
{
dfsI(i);
}
}

memset(first2,-1,sizeof(first2));
num=0;
for(u=1;u<=n;u++)
{
for(i=first1[u];i!=-1;i=edge1[i].next)
{
v=edge1[i].v;
if(belong[u]!=belong[v])
{
addedge(belong[u],belong[v],first2,edge2);
}
}
}

return;
}

void dfsI(int cur)
{
int i,v;
stk.push(cur);
book[cur]=1;
cnt++;
dfn[cur]=cnt;
low[cur]=cnt;
for(i=first1[cur];i!=-1;i=edge1[i].next)
{
v=edge1[i].v;
if(dfn[v]==0)
{
dfsI(v);
if(low[v]<low[cur])
{
low[cur]=low[v];
}
}
else
{
if(book[v]==1&&dfn[v]<low[cur])
{
low[cur]=dfn[v];
}
}
}

if(dfn[cur]==low[cur])
{
sum++;
while(!stk.empty())
{
v=stk.top();
stk.pop();
book[v]=0;
belong[v]=sum;
if(v==cur) break;
}
}

return;
}

void calculate()
{
int i,j;
memset(mat,0,sizeof(mat));
for(i=1;i<=sum;i++)
{
memset(book,0,sizeof(book));
book[i]=1;
dfsII(i,i);
}
flag=1;
for(i=1;i<=sum;i++)
{
for(j=1;j<=sum;j++)
{
if(mat[i][j]==0&&mat[j][i]==0)
{
flag=0;
break;
}
}
if(flag==0) break;
}
return;
}

void dfsII(int cur,int f)
{
int i,v;
mat[f][cur]=1;
for(i=first2[cur];i!=-1;i=edge2[i].next)
{
v=edge2[i].v;
if(book[v]==0)
{
book[v]=1;
dfsII(v,f);
}
}
return;
}

 

 

以下是暴力版

 

#include <bits/stdc++.h>
using namespace std;

struct node
{
int v;
int next;
};

node edge[6010];
int e[1010][1010];
int first[1010],book[1010];
int n,m,num;

void addedge(int u,int v)
{
edge[num].v=v;
edge[num].next=first[u];
first[u]=num++;
return;
}

int safari();
void dfs(int cur,int pre);

int main()
{
int t,ans,i,u,v;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(first,-1,sizeof(first));
num=0;
for(i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
}
ans=safari();
if(ans==0) printf("Light my fire!\n");
else printf("I love you my love and our love save us!\n");
}
return 0;
}

int safari()
{
int i,j,ans;
memset(e,0,sizeof(e));
for(i=1;i<=n;i++)
{
memset(book,0,sizeof(book));
book[i]=1;
dfs(i,i);
}
ans=1;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j) continue;
if(e[i][j]==0&&e[j][i]==0)
{
ans=0;
break;
}
}
if(ans==0) break;
}
return ans;
}

void dfs(int cur,int pre)
{
int i,v;
for(i=first[cur];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(book[v]==0)
{
e[pre][v]=1;
book[v]=1;
dfs(v,pre);
}
}
return;
}

 

 

 

 

 


举报

相关推荐

0 条评论