数学思想做这个题,就有点套路了。这个题目要求的是什么的呢?一个点能到其他所有的点。如果这样的以下条件肯定会成立,假设点1 2 3 4 5;
1是根节点,有一条路径1->2->3->4->5;
所以1 2 3 4 5 . 1代表的是有路径,0代表没有路径,如果1->2有路径,把(1,2)(2,1)都标记了
1 1 1 1 1 1 这个图肯定全为1.对每个点进行深搜,最坏的情况是,所有的点成为一个大的环
2 0 1 1 1 1 如果120组数据全都是这种情况,会超时3-6秒,但是不存在的,1800ms过了
3 0 0 1 1 1
4 0 0 0 1 1
5 0 0 0 0 1
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
vector <int>g[1005];
bool flag[1005][1005];
bool vis[1005];
int cnt,n;
void dfs(int u)
{
for(int j=0;j<g[u].size();j++)
{
int v=g[u][j];
flag[cnt][v]=1;
flag[v][cnt]=1;
if(!vis[v])
{
vis[v]=1;
dfs(v);
}
}
}
void solve()
{
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
cnt=i;
vis[i]=1;
dfs(i);
flag[i][i]=1;
}
}
int main()
{
//freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
int m,a,b;
memset(flag,0,sizeof(flag));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)g[i].clear();
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
g[a].pb(b);
}
solve();
int ans=1;
for(int i=1;i<=n;i++)
{for(int j=1;j<=n;j++)
{//cout<<flag[i][j]<<" ";
if(!flag[i][j])ans=0;
}
//cout<<endl;
}
if(ans)printf("I love you my love and our love save us!\n");
else puts("Light my fire!");
}
return 0;
}
强联通分量
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
const int maxn=1100;
int V; //顶点数
vector<int>G[maxn]; //图的邻接表表示
vector<int>rG[maxn];//把边反向后的图
vector<int>vs; //后序遍历顺序的顶点列表
bool used[maxn]; //访问标记
int cmp[maxn]; //所属强连通分量的拓扑序
int in[maxn];
vector<int>g[maxn];
queue<int >q;
void init()
{
for(int i=0; i<maxn; i++)
G[i].clear(),rG[i].clear(),g[i].clear();
while(!q.empty())q.pop();
}
void add_edge(int from,int to)
{
G[from].pb(to);
rG[to].pb(from);
}
void dfs(int u)
{
used[u]=true;
for(int i=0; i<(int)G[u].size(); i++)
{
if(!used[G[u][i]])dfs(G[u][i]);
}
vs.push_back(u);
}
void rdfs(int u,int k)
{
used[u]=true;
cmp[u]=k;
for(int i=0; i<(int)rG[u].size(); i++)
{
if(!used[rG[u][i]])rdfs(rG[u][i],k);
}
}
int scc()
{
memset(used,0,sizeof(used));
vs.clear();
for(int v=1; v<=V; v++)
if(!used[v])dfs(v);
memset(used,0,sizeof(used));
int k=0;
for(int i=vs.size()-1; i>=0; i--)
{
if(!used[vs[i]])rdfs(vs[i],k++);
}
//以上为强联通分量模板,in数组处理缩点
memset(in,0,sizeof(in));
for(int i=1; i<=V; i++)
for(int j=0; j<(int)G[i].size(); j++)
{
int v=G[i][j];
// cout<<v<<endl;
if(cmp[i]!=cmp[v])
{
in[cmp[v]]++;
g[cmp[i]].pb(cmp[v]);
}
}
return k;
}
int main()
{
//freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
//ios::sync_with_stdio(false);
int t;
scanf("%d",&t);
while(t--)
{
init();
int m,a,b;
scanf("%d%d",&V,&m);
for(int i=1; i<=m; i++)
{
scanf("%d%d",&a,&b);
add_edge(a,b);
}
int k=scc();
int flag=0;
for(int i=0; i<k; i++)
{
if(in[i]==0)flag++,q.push(i);
if(flag==2)break;
}
if(flag<2)
{
while(!q.empty())
{
int p=q.front();
q.pop();
flag=0;
for(int i=0; i<(int)g[p].size(); i++)
{
int v=g[p][i];
in[v]--;
if(in[v]==0)flag++,q.push(v);
}
if(flag>=2)break;
}
}
if(flag<2) puts("I love you my love and our love save us!");
else puts("Light my fire!");
}
return 0;
}